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/>.
29 #include "build/debug.h"
31 #include "drivers/bus_spi.h"
32 #include "drivers/bus_spi_impl.h"
33 #include "drivers/dma.h"
34 #include "drivers/exti.h"
35 #include "drivers/io.h"
36 #include "drivers/rcc.h"
38 #include "pg/bus_spi.h"
40 const spiHardware_t spiHardware
[] = {
42 // Remapping is not supported and corresponding lines are commented out.
43 // There also is some errata that may prevent these assignments from working:
44 // http://www.st.com/content/ccc/resource/technical/document/errata_sheet/7d/02/75/64/17/fc/4d/fd/CD00190234.pdf/files/CD00190234.pdf/jcr:content/translations/en.CD00190234.pdf
50 // { DEFIO_TAG_E(PB3) },
54 // { DEFIO_TAG_E(PB4) },
58 // { DEFIO_TAG_E(PB5) },
60 .rcc
= RCC_APB2(SPI1
),
66 { DEFIO_TAG_E(PB13
) },
67 // { DEFIO_TAG_E(PB3) },
70 { DEFIO_TAG_E(PB14
) },
71 // { DEFIO_TAG_E(PB4) },
74 { DEFIO_TAG_E(PB15
) },
75 // { DEFIO_TAG_E(PB5) },
77 .rcc
= RCC_APB1(SPI2
),
83 #define GPIO_AF_SPI1 GPIO_AF_5
86 #define GPIO_AF_SPI2 GPIO_AF_5
89 #define GPIO_AF_SPI3 GPIO_AF_6
100 { DEFIO_TAG_E(PA6
) },
101 { DEFIO_TAG_E(PB4
) },
104 { DEFIO_TAG_E(PA7
) },
105 { DEFIO_TAG_E(PB5
) },
108 .rcc
= RCC_APB2(SPI1
),
114 { DEFIO_TAG_E(PB13
) },
115 { DEFIO_TAG_E(PB3
) },
118 { DEFIO_TAG_E(PB14
) },
119 { DEFIO_TAG_E(PB4
) },
122 { DEFIO_TAG_E(PB15
) },
123 { DEFIO_TAG_E(PB5
) },
126 .rcc
= RCC_APB1(SPI2
),
132 { DEFIO_TAG_E(PB3
) },
133 { DEFIO_TAG_E(PC10
) },
136 { DEFIO_TAG_E(PB4
) },
137 { DEFIO_TAG_E(PC11
) },
140 { DEFIO_TAG_E(PB5
) },
141 { DEFIO_TAG_E(PC12
) },
144 .rcc
= RCC_APB1(SPI3
),
152 { DEFIO_TAG_E(PA5
) },
153 { DEFIO_TAG_E(PB3
) },
156 { DEFIO_TAG_E(PA6
) },
157 { DEFIO_TAG_E(PB4
) },
160 { DEFIO_TAG_E(PA7
) },
161 { DEFIO_TAG_E(PB5
) },
164 .rcc
= RCC_APB2(SPI1
),
170 { DEFIO_TAG_E(PB10
) },
171 { DEFIO_TAG_E(PB13
) },
174 { DEFIO_TAG_E(PB14
) },
175 { DEFIO_TAG_E(PC2
) },
178 { DEFIO_TAG_E(PB15
) },
179 { DEFIO_TAG_E(PC3
) },
182 .rcc
= RCC_APB1(SPI2
),
188 { DEFIO_TAG_E(PB3
) },
189 { DEFIO_TAG_E(PC10
) },
192 { DEFIO_TAG_E(PB4
) },
193 { DEFIO_TAG_E(PC11
) },
196 { DEFIO_TAG_E(PB5
) },
197 { DEFIO_TAG_E(PC12
) },
200 .rcc
= RCC_APB1(SPI3
),
208 { DEFIO_TAG_E(PA5
), GPIO_AF5_SPI1
},
209 { DEFIO_TAG_E(PB3
), GPIO_AF5_SPI1
},
212 { DEFIO_TAG_E(PA6
), GPIO_AF5_SPI1
},
213 { DEFIO_TAG_E(PB4
), GPIO_AF5_SPI1
},
216 { DEFIO_TAG_E(PA7
), GPIO_AF5_SPI1
},
217 { DEFIO_TAG_E(PB5
), GPIO_AF5_SPI1
},
219 .rcc
= RCC_APB2(SPI1
),
220 .dmaIrqHandler
= DMA2_ST3_HANDLER
,
226 { DEFIO_TAG_E(PA9
), GPIO_AF5_SPI2
},
227 { DEFIO_TAG_E(PB10
), GPIO_AF5_SPI2
},
228 { DEFIO_TAG_E(PB13
), GPIO_AF5_SPI2
},
229 { DEFIO_TAG_E(PD3
), GPIO_AF5_SPI2
},
232 { DEFIO_TAG_E(PB14
), GPIO_AF5_SPI2
},
233 { DEFIO_TAG_E(PC2
), GPIO_AF5_SPI2
},
236 { DEFIO_TAG_E(PB15
), GPIO_AF5_SPI2
},
237 { DEFIO_TAG_E(PC1
), GPIO_AF5_SPI2
},
238 { DEFIO_TAG_E(PC3
), GPIO_AF5_SPI2
},
240 .rcc
= RCC_APB1(SPI2
),
241 .dmaIrqHandler
= DMA1_ST4_HANDLER
,
247 { DEFIO_TAG_E(PB3
), GPIO_AF6_SPI3
},
248 { DEFIO_TAG_E(PC10
), GPIO_AF6_SPI3
},
251 { DEFIO_TAG_E(PB4
), GPIO_AF6_SPI3
},
252 { DEFIO_TAG_E(PC11
), GPIO_AF6_SPI3
},
255 { DEFIO_TAG_E(PB2
), GPIO_AF7_SPI3
},
256 { DEFIO_TAG_E(PB5
), GPIO_AF6_SPI3
},
257 { DEFIO_TAG_E(PC12
), GPIO_AF6_SPI3
},
258 { DEFIO_TAG_E(PD6
), GPIO_AF5_SPI3
},
260 .rcc
= RCC_APB1(SPI3
),
261 .dmaIrqHandler
= DMA1_ST7_HANDLER
,
267 { DEFIO_TAG_E(PE2
), GPIO_AF5_SPI4
},
268 { DEFIO_TAG_E(PE12
), GPIO_AF5_SPI4
},
271 { DEFIO_TAG_E(PE5
), GPIO_AF5_SPI4
},
272 { DEFIO_TAG_E(PE13
), GPIO_AF5_SPI4
},
275 { DEFIO_TAG_E(PE6
), GPIO_AF5_SPI4
},
276 { DEFIO_TAG_E(PE14
), GPIO_AF5_SPI4
},
278 .rcc
= RCC_APB2(SPI4
),
279 .dmaIrqHandler
= DMA2_ST1_HANDLER
,
287 { DEFIO_TAG_E(PA5
), GPIO_AF5_SPI1
},
288 { DEFIO_TAG_E(PB3
), GPIO_AF5_SPI1
},
291 { DEFIO_TAG_E(PA6
), GPIO_AF5_SPI1
},
292 { DEFIO_TAG_E(PB4
), GPIO_AF5_SPI1
},
295 { DEFIO_TAG_E(PA7
), GPIO_AF5_SPI1
},
296 { DEFIO_TAG_E(PB5
), GPIO_AF5_SPI1
},
297 { DEFIO_TAG_E(PD7
), GPIO_AF5_SPI1
},
299 .rcc
= RCC_APB2(SPI1
),
300 //.dmaIrqHandler = DMA2_ST3_HANDLER,
306 { DEFIO_TAG_E(PA9
), GPIO_AF5_SPI2
},
307 { DEFIO_TAG_E(PA12
), GPIO_AF5_SPI2
},
308 { DEFIO_TAG_E(PB10
), GPIO_AF5_SPI2
},
309 { DEFIO_TAG_E(PB13
), GPIO_AF5_SPI2
},
310 { DEFIO_TAG_E(PD3
), GPIO_AF5_SPI2
},
313 { DEFIO_TAG_E(PB14
), GPIO_AF5_SPI2
},
314 { DEFIO_TAG_E(PC2
), GPIO_AF5_SPI2
},
317 { DEFIO_TAG_E(PB15
), GPIO_AF5_SPI2
},
318 { DEFIO_TAG_E(PC1
), GPIO_AF5_SPI2
},
319 { DEFIO_TAG_E(PC3
), GPIO_AF5_SPI2
},
321 .rcc
= RCC_APB1L(SPI2
),
322 //.dmaIrqHandler = DMA1_ST4_HANDLER,
328 { DEFIO_TAG_E(PB3
), GPIO_AF6_SPI3
},
329 { DEFIO_TAG_E(PC10
), GPIO_AF6_SPI3
},
332 { DEFIO_TAG_E(PB4
), GPIO_AF6_SPI3
},
333 { DEFIO_TAG_E(PC11
), GPIO_AF6_SPI3
},
336 { DEFIO_TAG_E(PB2
), GPIO_AF7_SPI3
},
337 { DEFIO_TAG_E(PB5
), GPIO_AF7_SPI3
},
338 { DEFIO_TAG_E(PC12
), GPIO_AF6_SPI3
},
339 { DEFIO_TAG_E(PD6
), GPIO_AF5_SPI3
},
341 .rcc
= RCC_APB1L(SPI3
),
342 //.dmaIrqHandler = DMA1_ST7_HANDLER,
348 { DEFIO_TAG_E(PE2
), GPIO_AF5_SPI4
},
349 { DEFIO_TAG_E(PE12
), GPIO_AF5_SPI4
},
352 { DEFIO_TAG_E(PE5
), GPIO_AF5_SPI4
},
353 { DEFIO_TAG_E(PE13
), GPIO_AF5_SPI4
},
356 { DEFIO_TAG_E(PE6
), GPIO_AF5_SPI4
},
357 { DEFIO_TAG_E(PE14
), GPIO_AF5_SPI4
},
359 .rcc
= RCC_APB2(SPI4
),
360 //.dmaIrqHandler = DMA2_ST1_HANDLER,
366 { DEFIO_TAG_E(PF7
), GPIO_AF5_SPI5
},
369 { DEFIO_TAG_E(PF8
), GPIO_AF5_SPI5
},
372 { DEFIO_TAG_E(PF11
), GPIO_AF5_SPI5
},
374 .rcc
= RCC_APB2(SPI5
),
375 //.dmaIrqHandler = DMA2_ST1_HANDLER,
381 { DEFIO_TAG_E(PA5
), GPIO_AF8_SPI6
},
382 { DEFIO_TAG_E(PB3
), GPIO_AF8_SPI6
},
385 { DEFIO_TAG_E(PA6
), GPIO_AF8_SPI6
},
386 { DEFIO_TAG_E(PB4
), GPIO_AF8_SPI6
},
389 { DEFIO_TAG_E(PA7
), GPIO_AF8_SPI6
},
390 { DEFIO_TAG_E(PB5
), GPIO_AF8_SPI6
},
392 .rcc
= RCC_APB4(SPI6
),
393 //.dmaIrqHandler = DMA2_ST1_HANDLER,
401 { DEFIO_TAG_E(PA5
), GPIO_AF5_SPI1
},
402 { DEFIO_TAG_E(PB3
), GPIO_AF5_SPI1
},
405 { DEFIO_TAG_E(PA6
), GPIO_AF5_SPI1
},
406 { DEFIO_TAG_E(PB4
), GPIO_AF5_SPI1
},
409 { DEFIO_TAG_E(PA7
), GPIO_AF5_SPI1
},
410 { DEFIO_TAG_E(PB5
), GPIO_AF5_SPI1
},
412 .rcc
= RCC_APB2(SPI1
),
413 //.dmaIrqHandler = DMA2_ST3_HANDLER,
419 { DEFIO_TAG_E(PB13
), GPIO_AF5_SPI2
},
422 { DEFIO_TAG_E(PA10
), GPIO_AF5_SPI2
},
423 { DEFIO_TAG_E(PB14
), GPIO_AF5_SPI2
},
426 { DEFIO_TAG_E(PA11
), GPIO_AF5_SPI2
},
427 { DEFIO_TAG_E(PB15
), GPIO_AF5_SPI2
},
429 .rcc
= RCC_APB11(SPI2
),
430 //.dmaIrqHandler = DMA1_ST4_HANDLER,
436 { DEFIO_TAG_E(PB3
), GPIO_AF6_SPI3
},
437 { DEFIO_TAG_E(PC10
), GPIO_AF6_SPI3
},
440 { DEFIO_TAG_E(PB4
), GPIO_AF6_SPI3
},
441 { DEFIO_TAG_E(PC11
), GPIO_AF6_SPI3
},
444 { DEFIO_TAG_E(PB5
), GPIO_AF6_SPI3
},
445 { DEFIO_TAG_E(PC12
), GPIO_AF6_SPI3
},
447 .rcc
= RCC_APB11(SPI3
),
448 //.dmaIrqHandler = DMA1_ST7_HANDLER,
453 void spiPinConfigure(const spiPinConfig_t
*pConfig
)
455 for (size_t hwindex
= 0 ; hwindex
< ARRAYLEN(spiHardware
) ; hwindex
++) {
456 const spiHardware_t
*hw
= &spiHardware
[hwindex
];
462 SPIDevice device
= hw
->device
;
463 spiDevice_t
*pDev
= &spiDevice
[device
];
465 for (int pindex
= 0 ; pindex
< MAX_SPI_PIN_SEL
; pindex
++) {
466 if (pConfig
[device
].ioTagSck
== hw
->sckPins
[pindex
].pin
) {
467 pDev
->sck
= hw
->sckPins
[pindex
].pin
;
468 #if defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
469 pDev
->sckAF
= hw
->sckPins
[pindex
].af
;
472 if (pConfig
[device
].ioTagMiso
== hw
->misoPins
[pindex
].pin
) {
473 pDev
->miso
= hw
->misoPins
[pindex
].pin
;
474 #if defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
475 pDev
->misoAF
= hw
->misoPins
[pindex
].af
;
478 if (pConfig
[device
].ioTagMosi
== hw
->mosiPins
[pindex
].pin
) {
479 pDev
->mosi
= hw
->mosiPins
[pindex
].pin
;
480 #if defined(STM32F7) || defined(STM32H7) || defined(STM32G4)
481 pDev
->mosiAF
= hw
->mosiPins
[pindex
].af
;
486 if (pDev
->sck
&& pDev
->miso
&& pDev
->mosi
) {
488 #if !(defined(STM32F7) || defined(STM32H7) || defined(STM32G4))
492 pDev
->leadingEdge
= false; // XXX Should be part of transfer context
493 #if defined(USE_DMA) && defined(USE_HAL_DRIVER)
494 pDev
->dmaIrqHandler
= hw
->dmaIrqHandler
;