diff --git a/src/main/drivers/bus_spi_hal_ll.c b/src/main/drivers/bus_spi_hal_ll.c index fac8a82761a..ce6fbde9595 100644 --- a/src/main/drivers/bus_spi_hal_ll.c +++ b/src/main/drivers/bus_spi_hal_ll.c @@ -89,109 +89,159 @@ static const uint32_t spiDivisorMapSlow[] = { #endif #if defined(STM32H7) -static spiDevice_t spiHardwareMap[SPIDEV_COUNT] = { +#include "bus_spi_stm32h7xx.h" + +// Auto-resolve SPI AF per pin from the lookup table in bus_spi_stm32h7xx.h. +// Targets may still define individual SPI*_SCK/MISO/MOSI_AF values in target.h +// to override; explicit defines take priority via these #ifndef guards. #ifdef USE_SPI_DEVICE_1 -#if defined(SPI1_SCK_AF) || defined(SPI1_MISO_AF) || defined(SPI1_MOSI_AF) -#if !defined(SPI1_SCK_AF) || !defined(SPI1_MISO_AF) || !defined(SPI1_MOSI_AF) -#error SPI1: SCK, MISO and MOSI AFs should be defined together in target.h! +#ifndef SPI1_SCK_AF +#define SPI1_SCK_AF SPI_PIN_AF_HELPER(1, SPI1_SCK_PIN) #endif - { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = SPI1_SCK_AF, .misoAF = SPI1_MISO_AF, .mosiAF = SPI1_MOSI_AF, .divisorMap = spiDivisorMapFast }, -#else - { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = GPIO_AF5_SPI1, .misoAF = GPIO_AF5_SPI1, .mosiAF = GPIO_AF5_SPI1, .divisorMap = spiDivisorMapFast }, +#ifndef SPI1_MISO_AF +#define SPI1_MISO_AF SPI_PIN_AF_HELPER(1, SPI1_MISO_PIN) +#endif +#ifndef SPI1_MOSI_AF +#define SPI1_MOSI_AF SPI_PIN_AF_HELPER(1, SPI1_MOSI_PIN) #endif -#else - { .dev = NULL }, // No SPI1 #endif #ifdef USE_SPI_DEVICE_2 -#if defined(SPI2_SCK_AF) || defined(SPI2_MISO_AF) || defined(SPI2_MOSI_AF) -#if !defined(SPI2_SCK_AF) || !defined(SPI2_MISO_AF) || !defined(SPI2_MOSI_AF) -#error SPI2: SCK, MISO and MOSI AFs should be defined together in target.h! +#ifndef SPI2_SCK_AF +#define SPI2_SCK_AF SPI_PIN_AF_HELPER(2, SPI2_SCK_PIN) #endif - { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1L(SPI2), .sckAF = SPI2_SCK_AF, .misoAF = SPI2_MISO_AF, .mosiAF = SPI2_MOSI_AF, .divisorMap = spiDivisorMapSlow }, +#ifndef SPI2_MISO_AF +#define SPI2_MISO_AF SPI_PIN_AF_HELPER(2, SPI2_MISO_PIN) +#endif +#ifndef SPI2_MOSI_AF +#define SPI2_MOSI_AF SPI_PIN_AF_HELPER(2, SPI2_MOSI_PIN) +#endif +#endif + +#ifdef USE_SPI_DEVICE_3 +#ifndef SPI3_SCK_AF +#define SPI3_SCK_AF SPI_PIN_AF_HELPER(3, SPI3_SCK_PIN) +#endif +#ifndef SPI3_MISO_AF +#define SPI3_MISO_AF SPI_PIN_AF_HELPER(3, SPI3_MISO_PIN) +#endif +#ifndef SPI3_MOSI_AF +#define SPI3_MOSI_AF SPI_PIN_AF_HELPER(3, SPI3_MOSI_PIN) +#endif +#endif + +#ifdef USE_SPI_DEVICE_4 +#ifndef SPI4_SCK_AF +#define SPI4_SCK_AF SPI_PIN_AF_HELPER(4, SPI4_SCK_PIN) +#endif +#ifndef SPI4_MISO_AF +#define SPI4_MISO_AF SPI_PIN_AF_HELPER(4, SPI4_MISO_PIN) +#endif +#ifndef SPI4_MOSI_AF +#define SPI4_MOSI_AF SPI_PIN_AF_HELPER(4, SPI4_MOSI_PIN) +#endif +#endif + +static spiDevice_t spiHardwareMap[SPIDEV_COUNT] = { +#ifdef USE_SPI_DEVICE_1 + { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = SPI1_SCK_AF, .misoAF = SPI1_MISO_AF, .mosiAF = SPI1_MOSI_AF, .divisorMap = spiDivisorMapFast }, #else - { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1L(SPI2), .sckAF = GPIO_AF5_SPI2, .misoAF = GPIO_AF5_SPI2, .mosiAF = GPIO_AF5_SPI2, .divisorMap = spiDivisorMapSlow }, + { .dev = NULL }, // No SPI1 #endif + +#ifdef USE_SPI_DEVICE_2 + { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1L(SPI2), .sckAF = SPI2_SCK_AF, .misoAF = SPI2_MISO_AF, .mosiAF = SPI2_MOSI_AF, .divisorMap = spiDivisorMapSlow }, #else { .dev = NULL }, // No SPI2 #endif #ifdef USE_SPI_DEVICE_3 -#if defined(SPI3_SCK_AF) || defined(SPI3_MISO_AF) || defined(SPI3_MOSI_AF) -#if !defined(SPI3_SCK_AF) || !defined(SPI3_MISO_AF) || !defined(SPI3_MOSI_AF) -#error SPI3: SCK, MISO and MOSI AFs should be defined together in target.h! -#endif { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1L(SPI3), .sckAF = SPI3_SCK_AF, .misoAF = SPI3_MISO_AF, .mosiAF = SPI3_MOSI_AF, .divisorMap = spiDivisorMapSlow }, -#else - { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1L(SPI3), .sckAF = GPIO_AF6_SPI3, .misoAF = GPIO_AF6_SPI3, .mosiAF = GPIO_AF6_SPI3, .divisorMap = spiDivisorMapSlow }, -#endif #else { .dev = NULL }, // No SPI3 #endif #ifdef USE_SPI_DEVICE_4 -#if defined(SPI4_SCK_AF) || defined(SPI4_MISO_AF) || defined(SPI4_MOSI_AF) -#if !defined(SPI4_SCK_AF) || !defined(SPI4_MISO_AF) || !defined(SPI4_MOSI_AF) -#error SPI4: SCK, MISO and MOSI AFs should be defined together in target.h! -#endif { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = SPI4_SCK_AF, .misoAF = SPI4_MISO_AF, .mosiAF = SPI4_MOSI_AF, .divisorMap = spiDivisorMapSlow } -#else - { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = GPIO_AF5_SPI4, .misoAF = GPIO_AF5_SPI4, .mosiAF = GPIO_AF5_SPI4, .divisorMap = spiDivisorMapSlow } -#endif #else { .dev = NULL } // No SPI4 #endif }; -#else -static spiDevice_t spiHardwareMap[] = { +#elif defined(STM32F7) +#include "bus_spi_stm32f7xx.h" + +// Auto-resolve SPI AF per pin from the lookup table in bus_spi_stm32f7xx.h. +// Targets may still define individual SPI*_SCK/MISO/MOSI_AF values in target.h +// to override; explicit defines take priority via these #ifndef guards. #ifdef USE_SPI_DEVICE_1 -#if defined(SPI1_SCK_AF) || defined(SPI1_MISO_AF) || defined(SPI1_MOSI_AF) -#if !defined(SPI1_SCK_AF) || !defined(SPI1_MISO_AF) || !defined(SPI1_MOSI_AF) -#error SPI1: SCK, MISO and MOSI AFs should be defined together in target.h! +#ifndef SPI1_SCK_AF +#define SPI1_SCK_AF SPI_PIN_AF_HELPER(1, SPI1_SCK_PIN) #endif - { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = SPI1_SCK_AF, .misoAF = SPI1_MISO_AF, .mosiAF = SPI1_MOSI_AF, .divisorMap = spiDivisorMapFast }, -#else - { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = GPIO_AF5_SPI1, .misoAF = GPIO_AF5_SPI1, .mosiAF = GPIO_AF5_SPI1, .divisorMap = spiDivisorMapFast }, +#ifndef SPI1_MISO_AF +#define SPI1_MISO_AF SPI_PIN_AF_HELPER(1, SPI1_MISO_PIN) +#endif +#ifndef SPI1_MOSI_AF +#define SPI1_MOSI_AF SPI_PIN_AF_HELPER(1, SPI1_MOSI_PIN) #endif -#else - { .dev = NULL }, // No SPI1 #endif #ifdef USE_SPI_DEVICE_2 -#if defined(SPI2_SCK_AF) || defined(SPI2_MISO_AF) || defined(SPI2_MOSI_AF) -#if !defined(SPI2_SCK_AF) || !defined(SPI2_MISO_AF) || !defined(SPI2_MOSI_AF) -#error SPI2: SCK, MISO and MOSI AFs should be defined together in target.h! +#ifndef SPI2_SCK_AF +#define SPI2_SCK_AF SPI_PIN_AF_HELPER(2, SPI2_SCK_PIN) #endif - { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .sckAF = SPI2_SCK_AF, .misoAF = SPI2_MISO_AF, .mosiAF = SPI2_MOSI_AF, .divisorMap = spiDivisorMapSlow }, +#ifndef SPI2_MISO_AF +#define SPI2_MISO_AF SPI_PIN_AF_HELPER(2, SPI2_MISO_PIN) +#endif +#ifndef SPI2_MOSI_AF +#define SPI2_MOSI_AF SPI_PIN_AF_HELPER(2, SPI2_MOSI_PIN) +#endif +#endif + +#ifdef USE_SPI_DEVICE_3 +#ifndef SPI3_SCK_AF +#define SPI3_SCK_AF SPI_PIN_AF_HELPER(3, SPI3_SCK_PIN) +#endif +#ifndef SPI3_MISO_AF +#define SPI3_MISO_AF SPI_PIN_AF_HELPER(3, SPI3_MISO_PIN) +#endif +#ifndef SPI3_MOSI_AF +#define SPI3_MOSI_AF SPI_PIN_AF_HELPER(3, SPI3_MOSI_PIN) +#endif +#endif + +#ifdef USE_SPI_DEVICE_4 +#ifndef SPI4_SCK_AF +#define SPI4_SCK_AF SPI_PIN_AF_HELPER(4, SPI4_SCK_PIN) +#endif +#ifndef SPI4_MISO_AF +#define SPI4_MISO_AF SPI_PIN_AF_HELPER(4, SPI4_MISO_PIN) +#endif +#ifndef SPI4_MOSI_AF +#define SPI4_MOSI_AF SPI_PIN_AF_HELPER(4, SPI4_MOSI_PIN) +#endif +#endif + +static spiDevice_t spiHardwareMap[] = { +#ifdef USE_SPI_DEVICE_1 + { .dev = SPI1, .nss = IO_TAG(SPI1_NSS_PIN), .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .sckAF = SPI1_SCK_AF, .misoAF = SPI1_MISO_AF, .mosiAF = SPI1_MOSI_AF, .divisorMap = spiDivisorMapFast }, #else - { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .sckAF = GPIO_AF5_SPI2, .misoAF = GPIO_AF5_SPI2, .mosiAF = GPIO_AF5_SPI2, .divisorMap = spiDivisorMapSlow }, + { .dev = NULL }, // No SPI1 #endif + +#ifdef USE_SPI_DEVICE_2 + { .dev = SPI2, .nss = IO_TAG(SPI2_NSS_PIN), .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .sckAF = SPI2_SCK_AF, .misoAF = SPI2_MISO_AF, .mosiAF = SPI2_MOSI_AF, .divisorMap = spiDivisorMapSlow }, #else { .dev = NULL }, // No SPI2 #endif #ifdef USE_SPI_DEVICE_3 -#if defined(SPI3_SCK_AF) || defined(SPI3_MISO_AF) || defined(SPI3_MOSI_AF) -#if !defined(SPI3_SCK_AF) || !defined(SPI3_MISO_AF) || !defined(SPI3_MOSI_AF) -#error SPI3: SCK, MISO and MOSI AFs should be defined together in target.h! -#endif { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .sckAF = SPI3_SCK_AF, .misoAF = SPI3_MISO_AF, .mosiAF = SPI3_MOSI_AF, .divisorMap = spiDivisorMapSlow }, -#else - { .dev = SPI3, .nss = IO_TAG(SPI3_NSS_PIN), .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .sckAF = GPIO_AF6_SPI3, .misoAF = GPIO_AF6_SPI3, .mosiAF = GPIO_AF6_SPI3, .divisorMap = spiDivisorMapSlow }, -#endif #else { .dev = NULL }, // No SPI3 #endif #ifdef USE_SPI_DEVICE_4 -#if defined(SPI4_SCK_AF) || defined(SPI4_MISO_AF) || defined(SPI4_MOSI_AF) -#if !defined(SPI4_SCK_AF) || !defined(SPI4_MISO_AF) || !defined(SPI4_MOSI_AF) -#error SPI3: SCK, MISO and MOSI AFs should be defined together in target.h! -#endif { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = SPI4_SCK_AF, .misoAF = SPI4_MISO_AF, .mosiAF = SPI4_MOSI_AF, .divisorMap = spiDivisorMapSlow } -#else - { .dev = SPI4, .nss = IO_TAG(SPI4_NSS_PIN), .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .sckAF = GPIO_AF5_SPI4, .misoAF = GPIO_AF5_SPI4, .mosiAF = GPIO_AF5_SPI4, .divisorMap = spiDivisorMapSlow } -#endif #else { .dev = NULL } // No SPI4 #endif diff --git a/src/main/drivers/bus_spi_stm32f7xx.h b/src/main/drivers/bus_spi_stm32f7xx.h new file mode 100644 index 00000000000..a43938e1e45 --- /dev/null +++ b/src/main/drivers/bus_spi_stm32f7xx.h @@ -0,0 +1,80 @@ +/* + * This file is part of INAV. + * + * INAV is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * INAV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with INAV. If not, see . + */ + +/* + * STM32F7 SPI pin alternate function lookup table. + * + * Usage: SPI_PIN_AF_HELPER(3, PB5) expands to SPI_PIN_AF_SPI3_PB5, + * which is defined below as GPIO_AF6_SPI3. + * + * AF assignments from STM32F722 datasheet (DS11853) and STM32F745 datasheet + * (DS10916), Table 9. + * + * NOTE: The F7 AF table differs from the H7 for SPI3/PB5: + * On F7, PB5 SPI3_MOSI is AF6 (the default). + * On H7, PB5 SPI3_MOSI is AF7 (an exception — see bus_spi_stm32h7xx.h). + * + * SPI1, SPI2, SPI4 pins are all AF5 with no exceptions. + * SPI3 SCK/MISO are AF6. SPI3 MOSI has pin-dependent exceptions: + * PB2 uses AF7 (not AF6). PD6 uses AF5 (not AF6). PC12 and PB5 use AF6. + */ + +#pragma once + +#include "common/utils.h" + +// Resolves to SPI_PIN_AF_SPIn_Pxy, defined below for each valid pin. +// If a pin is not in the table the build will fail with "undefined identifier", +// which is preferable to silently applying the wrong AF. +#define SPI_PIN_AF_HELPER(spi, pin) CONCAT4(SPI_PIN_AF_SPI, spi, _, pin) + +/* SPI1 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI1_PA5 GPIO_AF5_SPI1 // SCK +#define SPI_PIN_AF_SPI1_PA6 GPIO_AF5_SPI1 // MISO +#define SPI_PIN_AF_SPI1_PA7 GPIO_AF5_SPI1 // MOSI +#define SPI_PIN_AF_SPI1_PB3 GPIO_AF5_SPI1 // SCK +#define SPI_PIN_AF_SPI1_PB4 GPIO_AF5_SPI1 // MISO +#define SPI_PIN_AF_SPI1_PB5 GPIO_AF5_SPI1 // MOSI + +/* SPI2 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI2_PB13 GPIO_AF5_SPI2 // SCK +#define SPI_PIN_AF_SPI2_PB14 GPIO_AF5_SPI2 // MISO +#define SPI_PIN_AF_SPI2_PB15 GPIO_AF5_SPI2 // MOSI +#define SPI_PIN_AF_SPI2_PC1 GPIO_AF5_SPI2 // MOSI +#define SPI_PIN_AF_SPI2_PC2 GPIO_AF5_SPI2 // MISO +#define SPI_PIN_AF_SPI2_PC3 GPIO_AF5_SPI2 // MOSI + +/* + * SPI3 — SCK and MISO use AF6, but MOSI has pin-dependent exceptions. + * PB2 carries SPI3_MOSI on AF7 (not AF6). PD6 uses AF5. PB5 and PC12 use AF6. + */ +#define SPI_PIN_AF_SPI3_PB2 GPIO_AF7_SPI3 // MOSI — exception: AF7, not AF6 +#define SPI_PIN_AF_SPI3_PB3 GPIO_AF6_SPI3 // SCK +#define SPI_PIN_AF_SPI3_PB4 GPIO_AF6_SPI3 // MISO +#define SPI_PIN_AF_SPI3_PB5 GPIO_AF6_SPI3 // MOSI (AF6 on F7; H7 uses AF7 for this pin) +#define SPI_PIN_AF_SPI3_PC10 GPIO_AF6_SPI3 // SCK +#define SPI_PIN_AF_SPI3_PC11 GPIO_AF6_SPI3 // MISO +#define SPI_PIN_AF_SPI3_PC12 GPIO_AF6_SPI3 // MOSI +#define SPI_PIN_AF_SPI3_PD6 GPIO_AF5_SPI3 // MOSI — exception: AF5, not AF6 + +/* SPI4 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI4_PE2 GPIO_AF5_SPI4 // SCK +#define SPI_PIN_AF_SPI4_PE5 GPIO_AF5_SPI4 // MISO +#define SPI_PIN_AF_SPI4_PE6 GPIO_AF5_SPI4 // MOSI +#define SPI_PIN_AF_SPI4_PE12 GPIO_AF5_SPI4 // SCK +#define SPI_PIN_AF_SPI4_PE13 GPIO_AF5_SPI4 // MISO +#define SPI_PIN_AF_SPI4_PE14 GPIO_AF5_SPI4 // MOSI diff --git a/src/main/drivers/bus_spi_stm32h7xx.h b/src/main/drivers/bus_spi_stm32h7xx.h new file mode 100644 index 00000000000..286e5859816 --- /dev/null +++ b/src/main/drivers/bus_spi_stm32h7xx.h @@ -0,0 +1,81 @@ +/* + * This file is part of INAV. + * + * INAV is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * INAV is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with INAV. If not, see . + */ + +/* + * STM32H7 SPI pin alternate function lookup table. + * + * Usage: SPI_PIN_AF_HELPER(3, PB5) expands to SPI_PIN_AF_SPI3_PB5, + * which is defined below as GPIO_AF7_SPI3. + * + * This allows bus_spi_hal_ll.c to resolve the correct AF per pin automatically, + * without requiring each target to define SPI*_SCK_AF / SPI*_MISO_AF / SPI*_MOSI_AF + * manually in target.h. Targets may still override individual values if needed. + * + * Alternate function assignments are from the STM32H743 datasheet (DS12110), + * Tables 10-14. + */ + +#pragma once + +#include "common/utils.h" + +// Resolves to SPI_PIN_AF_SPIn_Pxy, which is defined below for each valid pin. +// If a pin is not in the table the build will fail with "undefined identifier", +// which is preferable to silently applying the wrong AF. +#define SPI_PIN_AF_HELPER(spi, pin) CONCAT4(SPI_PIN_AF_SPI, spi, _, pin) + +/* SPI1 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI1_PA5 GPIO_AF5_SPI1 // SCK +#define SPI_PIN_AF_SPI1_PA6 GPIO_AF5_SPI1 // MISO +#define SPI_PIN_AF_SPI1_PA7 GPIO_AF5_SPI1 // MOSI +#define SPI_PIN_AF_SPI1_PB3 GPIO_AF5_SPI1 // SCK +#define SPI_PIN_AF_SPI1_PB4 GPIO_AF5_SPI1 // MISO +#define SPI_PIN_AF_SPI1_PB5 GPIO_AF5_SPI1 // MOSI +#define SPI_PIN_AF_SPI1_PD7 GPIO_AF5_SPI1 // MOSI + +/* SPI2 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI2_PA9 GPIO_AF5_SPI2 // SCK +#define SPI_PIN_AF_SPI2_PB10 GPIO_AF5_SPI2 // SCK +#define SPI_PIN_AF_SPI2_PB13 GPIO_AF5_SPI2 // SCK +#define SPI_PIN_AF_SPI2_PB14 GPIO_AF5_SPI2 // MISO +#define SPI_PIN_AF_SPI2_PB15 GPIO_AF5_SPI2 // MOSI +#define SPI_PIN_AF_SPI2_PC1 GPIO_AF5_SPI2 // MOSI +#define SPI_PIN_AF_SPI2_PC2 GPIO_AF5_SPI2 // MISO +#define SPI_PIN_AF_SPI2_PC3 GPIO_AF5_SPI2 // MOSI +#define SPI_PIN_AF_SPI2_PD3 GPIO_AF5_SPI2 // SCK + +/* + * SPI3 — SCK and MISO use AF6, but MOSI has pin-dependent exceptions. + * PB2 and PB5 carry SPI3_MOSI on AF7 (not AF6). PD6 uses AF5. + * This is the only SPI bus on STM32H743 where a single-AF fallback is wrong. + */ +#define SPI_PIN_AF_SPI3_PB2 GPIO_AF7_SPI3 // MOSI — exception: AF7, not AF6 +#define SPI_PIN_AF_SPI3_PB3 GPIO_AF6_SPI3 // SCK +#define SPI_PIN_AF_SPI3_PB4 GPIO_AF6_SPI3 // MISO +#define SPI_PIN_AF_SPI3_PB5 GPIO_AF7_SPI3 // MOSI — exception: AF7, not AF6 +#define SPI_PIN_AF_SPI3_PC10 GPIO_AF6_SPI3 // SCK +#define SPI_PIN_AF_SPI3_PC11 GPIO_AF6_SPI3 // MISO +#define SPI_PIN_AF_SPI3_PC12 GPIO_AF6_SPI3 // MOSI +#define SPI_PIN_AF_SPI3_PD6 GPIO_AF5_SPI3 // MOSI — exception: AF5, not AF6 + +/* SPI4 — all data pins use AF5 */ +#define SPI_PIN_AF_SPI4_PE2 GPIO_AF5_SPI4 // SCK +#define SPI_PIN_AF_SPI4_PE5 GPIO_AF5_SPI4 // MISO +#define SPI_PIN_AF_SPI4_PE6 GPIO_AF5_SPI4 // MOSI +#define SPI_PIN_AF_SPI4_PE12 GPIO_AF5_SPI4 // SCK +#define SPI_PIN_AF_SPI4_PE13 GPIO_AF5_SPI4 // MISO +#define SPI_PIN_AF_SPI4_PE14 GPIO_AF5_SPI4 // MOSI