Merge pull request #9742 from mikeller/fix_spi_transaction_support
[betaflight.git] / src / main / drivers / bus_spi_pinconfig.c
blob0efa033e63760d5605eb88fd0be4ab26e4f7a60f
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 <stdbool.h>
22 #include <stdint.h>
23 #include <string.h>
25 #include "platform.h"
27 #ifdef USE_SPI
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[] = {
41 #ifdef STM32F1
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
46 .device = SPIDEV_1,
47 .reg = SPI1,
48 .sckPins = {
49 { DEFIO_TAG_E(PA5) },
50 // { DEFIO_TAG_E(PB3) },
52 .misoPins = {
53 { DEFIO_TAG_E(PA6) },
54 // { DEFIO_TAG_E(PB4) },
56 .mosiPins = {
57 { DEFIO_TAG_E(PA7) },
58 // { DEFIO_TAG_E(PB5) },
60 .rcc = RCC_APB2(SPI1),
63 .device = SPIDEV_2,
64 .reg = SPI2,
65 .sckPins = {
66 { DEFIO_TAG_E(PB13) },
67 // { DEFIO_TAG_E(PB3) },
69 .misoPins = {
70 { DEFIO_TAG_E(PB14) },
71 // { DEFIO_TAG_E(PB4) },
73 .mosiPins = {
74 { DEFIO_TAG_E(PB15) },
75 // { DEFIO_TAG_E(PB5) },
77 .rcc = RCC_APB1(SPI2),
79 #endif
80 #ifdef STM32F3
82 #ifndef GPIO_AF_SPI1
83 #define GPIO_AF_SPI1 GPIO_AF_5
84 #endif
85 #ifndef GPIO_AF_SPI2
86 #define GPIO_AF_SPI2 GPIO_AF_5
87 #endif
88 #ifndef GPIO_AF_SPI3
89 #define GPIO_AF_SPI3 GPIO_AF_6
90 #endif
93 .device = SPIDEV_1,
94 .reg = SPI1,
95 .sckPins = {
96 { DEFIO_TAG_E(PA5) },
97 { DEFIO_TAG_E(PB3) },
99 .misoPins = {
100 { DEFIO_TAG_E(PA6) },
101 { DEFIO_TAG_E(PB4) },
103 .mosiPins = {
104 { DEFIO_TAG_E(PA7) },
105 { DEFIO_TAG_E(PB5) },
107 .af = GPIO_AF_SPI1,
108 .rcc = RCC_APB2(SPI1),
111 .device = SPIDEV_2,
112 .reg = SPI2,
113 .sckPins = {
114 { DEFIO_TAG_E(PB13) },
115 { DEFIO_TAG_E(PB3) },
117 .misoPins = {
118 { DEFIO_TAG_E(PB14) },
119 { DEFIO_TAG_E(PB4) },
121 .mosiPins = {
122 { DEFIO_TAG_E(PB15) },
123 { DEFIO_TAG_E(PB5) },
125 .af = GPIO_AF_SPI2,
126 .rcc = RCC_APB1(SPI2),
129 .device = SPIDEV_3,
130 .reg = SPI3,
131 .sckPins = {
132 { DEFIO_TAG_E(PB3) },
133 { DEFIO_TAG_E(PC10) },
135 .misoPins = {
136 { DEFIO_TAG_E(PB4) },
137 { DEFIO_TAG_E(PC11) },
139 .mosiPins = {
140 { DEFIO_TAG_E(PB5) },
141 { DEFIO_TAG_E(PC12) },
143 .af = GPIO_AF_SPI3,
144 .rcc = RCC_APB1(SPI3),
146 #endif
147 #ifdef STM32F4
149 .device = SPIDEV_1,
150 .reg = SPI1,
151 .sckPins = {
152 { DEFIO_TAG_E(PA5) },
153 { DEFIO_TAG_E(PB3) },
155 .misoPins = {
156 { DEFIO_TAG_E(PA6) },
157 { DEFIO_TAG_E(PB4) },
159 .mosiPins = {
160 { DEFIO_TAG_E(PA7) },
161 { DEFIO_TAG_E(PB5) },
163 .af = GPIO_AF_SPI1,
164 .rcc = RCC_APB2(SPI1),
167 .device = SPIDEV_2,
168 .reg = SPI2,
169 .sckPins = {
170 { DEFIO_TAG_E(PB10) },
171 { DEFIO_TAG_E(PB13) },
173 .misoPins = {
174 { DEFIO_TAG_E(PB14) },
175 { DEFIO_TAG_E(PC2) },
177 .mosiPins = {
178 { DEFIO_TAG_E(PB15) },
179 { DEFIO_TAG_E(PC3) },
181 .af = GPIO_AF_SPI2,
182 .rcc = RCC_APB1(SPI2),
185 .device = SPIDEV_3,
186 .reg = SPI3,
187 .sckPins = {
188 { DEFIO_TAG_E(PB3) },
189 { DEFIO_TAG_E(PC10) },
191 .misoPins = {
192 { DEFIO_TAG_E(PB4) },
193 { DEFIO_TAG_E(PC11) },
195 .mosiPins = {
196 { DEFIO_TAG_E(PB5) },
197 { DEFIO_TAG_E(PC12) },
199 .af = GPIO_AF_SPI3,
200 .rcc = RCC_APB1(SPI3),
202 #endif
203 #ifdef STM32F7
205 .device = SPIDEV_1,
206 .reg = SPI1,
207 .sckPins = {
208 { DEFIO_TAG_E(PA5), GPIO_AF5_SPI1 },
209 { DEFIO_TAG_E(PB3), GPIO_AF5_SPI1 },
211 .misoPins = {
212 { DEFIO_TAG_E(PA6), GPIO_AF5_SPI1 },
213 { DEFIO_TAG_E(PB4), GPIO_AF5_SPI1 },
215 .mosiPins = {
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,
223 .device = SPIDEV_2,
224 .reg = SPI2,
225 .sckPins = {
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 },
231 .misoPins = {
232 { DEFIO_TAG_E(PB14), GPIO_AF5_SPI2 },
233 { DEFIO_TAG_E(PC2), GPIO_AF5_SPI2 },
235 .mosiPins = {
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,
244 .device = SPIDEV_3,
245 .reg = SPI3,
246 .sckPins = {
247 { DEFIO_TAG_E(PB3), GPIO_AF6_SPI3 },
248 { DEFIO_TAG_E(PC10), GPIO_AF6_SPI3 },
250 .misoPins = {
251 { DEFIO_TAG_E(PB4), GPIO_AF6_SPI3 },
252 { DEFIO_TAG_E(PC11), GPIO_AF6_SPI3 },
254 .mosiPins = {
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,
264 .device = SPIDEV_4,
265 .reg = SPI4,
266 .sckPins = {
267 { DEFIO_TAG_E(PE2), GPIO_AF5_SPI4 },
268 { DEFIO_TAG_E(PE12), GPIO_AF5_SPI4 },
270 .misoPins = {
271 { DEFIO_TAG_E(PE5), GPIO_AF5_SPI4 },
272 { DEFIO_TAG_E(PE13), GPIO_AF5_SPI4 },
274 .mosiPins = {
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,
281 #endif
282 #ifdef STM32H7
284 .device = SPIDEV_1,
285 .reg = SPI1,
286 .sckPins = {
287 { DEFIO_TAG_E(PA5), GPIO_AF5_SPI1 },
288 { DEFIO_TAG_E(PB3), GPIO_AF5_SPI1 },
290 .misoPins = {
291 { DEFIO_TAG_E(PA6), GPIO_AF5_SPI1 },
292 { DEFIO_TAG_E(PB4), GPIO_AF5_SPI1 },
294 .mosiPins = {
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,
303 .device = SPIDEV_2,
304 .reg = SPI2,
305 .sckPins = {
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 },
312 .misoPins = {
313 { DEFIO_TAG_E(PB14), GPIO_AF5_SPI2 },
314 { DEFIO_TAG_E(PC2), GPIO_AF5_SPI2 },
316 .mosiPins = {
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,
325 .device = SPIDEV_3,
326 .reg = SPI3,
327 .sckPins = {
328 { DEFIO_TAG_E(PB3), GPIO_AF6_SPI3 },
329 { DEFIO_TAG_E(PC10), GPIO_AF6_SPI3 },
331 .misoPins = {
332 { DEFIO_TAG_E(PB4), GPIO_AF6_SPI3 },
333 { DEFIO_TAG_E(PC11), GPIO_AF6_SPI3 },
335 .mosiPins = {
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,
345 .device = SPIDEV_4,
346 .reg = SPI4,
347 .sckPins = {
348 { DEFIO_TAG_E(PE2), GPIO_AF5_SPI4 },
349 { DEFIO_TAG_E(PE12), GPIO_AF5_SPI4 },
351 .misoPins = {
352 { DEFIO_TAG_E(PE5), GPIO_AF5_SPI4 },
353 { DEFIO_TAG_E(PE13), GPIO_AF5_SPI4 },
355 .mosiPins = {
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,
363 .device = SPIDEV_5,
364 .reg = SPI5,
365 .sckPins = {
366 { DEFIO_TAG_E(PF7), GPIO_AF5_SPI5 },
368 .misoPins = {
369 { DEFIO_TAG_E(PF8), GPIO_AF5_SPI5 },
371 .mosiPins = {
372 { DEFIO_TAG_E(PF11), GPIO_AF5_SPI5 },
374 .rcc = RCC_APB2(SPI5),
375 //.dmaIrqHandler = DMA2_ST1_HANDLER,
378 .device = SPIDEV_6,
379 .reg = SPI6,
380 .sckPins = {
381 { DEFIO_TAG_E(PA5), GPIO_AF8_SPI6 },
382 { DEFIO_TAG_E(PB3), GPIO_AF8_SPI6 },
384 .misoPins = {
385 { DEFIO_TAG_E(PA6), GPIO_AF8_SPI6 },
386 { DEFIO_TAG_E(PB4), GPIO_AF8_SPI6 },
388 .mosiPins = {
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,
395 #endif
398 void spiPinConfigure(const spiPinConfig_t *pConfig)
400 for (size_t hwindex = 0 ; hwindex < ARRAYLEN(spiHardware) ; hwindex++) {
401 const spiHardware_t *hw = &spiHardware[hwindex];
403 if (!hw->reg) {
404 continue;
407 SPIDevice device = hw->device;
408 spiDevice_t *pDev = &spiDevice[device];
410 for (int pindex = 0 ; pindex < MAX_SPI_PIN_SEL ; pindex++) {
411 if (pConfig[device].ioTagSck == hw->sckPins[pindex].pin) {
412 pDev->sck = hw->sckPins[pindex].pin;
413 #if defined(STM32F7) || defined(STM32H7)
414 pDev->sckAF = hw->sckPins[pindex].af;
415 #endif
417 if (pConfig[device].ioTagMiso == hw->misoPins[pindex].pin) {
418 pDev->miso = hw->misoPins[pindex].pin;
419 #if defined(STM32F7) || defined(STM32H7)
420 pDev->misoAF = hw->misoPins[pindex].af;
421 #endif
423 if (pConfig[device].ioTagMosi == hw->mosiPins[pindex].pin) {
424 pDev->mosi = hw->mosiPins[pindex].pin;
425 #if defined(STM32F7) || defined(STM32H7)
426 pDev->mosiAF = hw->mosiPins[pindex].af;
427 #endif
431 if (pDev->sck && pDev->miso && pDev->mosi) {
432 pDev->dev = hw->reg;
433 #if !(defined(STM32F7) || defined(STM32H7))
434 pDev->af = hw->af;
435 #endif
436 pDev->rcc = hw->rcc;
437 pDev->leadingEdge = false; // XXX Should be part of transfer context
438 #if defined(USE_DMA) && defined(USE_HAL_DRIVER)
439 pDev->dmaIrqHandler = hw->dmaIrqHandler;
440 #endif
444 #endif