diff --git a/Makefile b/Makefile
index e2b76957ed..5abbd9ff7a 100644
--- a/Makefile
+++ b/Makefile
@@ -680,6 +680,7 @@ COMMON_SRC = \
drivers/bus_i2c_config.c \
drivers/bus_i2c_soft.c \
drivers/bus_spi.c \
+ drivers/bus_spi_config.c \
drivers/bus_spi_soft.c \
drivers/buttons.c \
drivers/display.c \
@@ -898,6 +899,7 @@ SPEED_OPTIMISED_SRC := $(SPEED_OPTIMISED_SRC) \
SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
drivers/bus_i2c_config.c \
+ drivers/bus_spi_config.c \
drivers/serial_escserial.c \
drivers/serial_pinconfig.c \
drivers/serial_uart_init.c \
@@ -1023,9 +1025,10 @@ F7EXCLUDES = drivers/bus_spi.c \
SITLEXCLUDES = \
drivers/adc.c \
- drivers/bus_spi.c \
drivers/bus_i2c.c \
drivers/bus_i2c_config.c \
+ drivers/bus_spi.c \
+ drivers/bus_spi_config.c \
drivers/dma.c \
drivers/pwm_output.c \
drivers/timer.c \
diff --git a/src/main/drivers/accgyro/accgyro_spi_bmi160.c b/src/main/drivers/accgyro/accgyro_spi_bmi160.c
index 3852fa34dd..835ab25b2f 100644
--- a/src/main/drivers/accgyro/accgyro_spi_bmi160.c
+++ b/src/main/drivers/accgyro/accgyro_spi_bmi160.c
@@ -103,6 +103,7 @@ bool bmi160Detect(const busDevice_t *bus)
return true;
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
+ IOHi(bus->spi.csnPin);
spiSetDivisor(BMI160_SPI_INSTANCE, BMI160_SPI_DIVISOR);
diff --git a/src/main/drivers/accgyro/accgyro_spi_icm20689.c b/src/main/drivers/accgyro/accgyro_spi_icm20689.c
index 9764f61732..cb73bf4311 100644
--- a/src/main/drivers/accgyro/accgyro_spi_icm20689.c
+++ b/src/main/drivers/accgyro/accgyro_spi_icm20689.c
@@ -69,6 +69,7 @@ static void icm20689SpiInit(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
+ IOHi(bus->spi.csnPin);
spiSetDivisor(ICM20689_SPI_INSTANCE, SPI_CLOCK_STANDARD);
diff --git a/src/main/drivers/accgyro/accgyro_spi_mpu6000.c b/src/main/drivers/accgyro/accgyro_spi_mpu6000.c
index fd9455a55e..3ce84e4a50 100644
--- a/src/main/drivers/accgyro/accgyro_spi_mpu6000.c
+++ b/src/main/drivers/accgyro/accgyro_spi_mpu6000.c
@@ -155,6 +155,7 @@ bool mpu6000SpiDetect(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
+ IOHi(bus->spi.csnPin);
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON);
diff --git a/src/main/drivers/accgyro/accgyro_spi_mpu6500.c b/src/main/drivers/accgyro/accgyro_spi_mpu6500.c
index e477c3a047..1afecf509a 100755
--- a/src/main/drivers/accgyro/accgyro_spi_mpu6500.c
+++ b/src/main/drivers/accgyro/accgyro_spi_mpu6500.c
@@ -77,6 +77,7 @@ static void mpu6500SpiInit(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
+ IOHi(bus->spi.csnPin);
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);
diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c
index b5aae9eca2..eb0c2fdbc6 100644
--- a/src/main/drivers/bus_spi.c
+++ b/src/main/drivers/bus_spi.c
@@ -72,14 +72,14 @@
static spiDevice_t spiHardwareMap[] = {
#if defined(STM32F1)
- { .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), .af = 0, false },
- { .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), .af = 0, false },
+ { .dev = SPI1, .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = 0, false },
+ { .dev = SPI2, .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = 0, false },
#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), .af = GPIO_AF_SPI1, false },
- { .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), .af = GPIO_AF_SPI2, false },
+ { .dev = SPI1, .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF_SPI1, false },
+ { .dev = SPI2, .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF_SPI2, false },
#endif
#if defined(STM32F3) || defined(STM32F4)
- { .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), .af = GPIO_AF_SPI3, false }
+ { .dev = SPI3, .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF_SPI3, false }
#endif
};
@@ -124,21 +124,11 @@ void spiInitDevice(SPIDevice device)
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af);
-
- if (spi->nss) {
- IOInit(IOGetByTag(spi->nss), OWNER_SPI_CS, RESOURCE_INDEX(device));
- IOConfigGPIOAF(IOGetByTag(spi->nss), SPI_IO_CS_CFG, spi->af);
- }
#endif
#if defined(STM32F10X)
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
-
- if (spi->nss) {
- IOInit(IOGetByTag(spi->nss), OWNER_SPI_CS, RESOURCE_INDEX(device));
- IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
- }
#endif
// Init SPI hardware
@@ -168,11 +158,6 @@ void spiInitDevice(SPIDevice device)
SPI_Init(spi->dev, &spiInit);
SPI_Cmd(spi->dev, ENABLE);
-
- if (spi->nss) {
- // Drive NSS high to disable connected SPI device.
- IOHi(IOGetByTag(spi->nss));
- }
}
bool spiInit(SPIDevice device)
diff --git a/src/main/drivers/bus_spi.h b/src/main/drivers/bus_spi.h
index 4b0bbf22e8..9803ae77d9 100644
--- a/src/main/drivers/bus_spi.h
+++ b/src/main/drivers/bus_spi.h
@@ -71,7 +71,6 @@ typedef enum SPIDevice {
typedef struct SPIDevice_s {
SPI_TypeDef *dev;
- ioTag_t nss;
ioTag_t sck;
ioTag_t mosi;
ioTag_t miso;
@@ -86,6 +85,7 @@ typedef struct SPIDevice_s {
#endif
} spiDevice_t;
+void spiPreInitCs(ioTag_t iotag);
bool spiInit(SPIDevice device);
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor);
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in);
diff --git a/src/main/drivers/bus_spi_config.c b/src/main/drivers/bus_spi_config.c
new file mode 100644
index 0000000000..0bef12dd59
--- /dev/null
+++ b/src/main/drivers/bus_spi_config.c
@@ -0,0 +1,36 @@
+/*
+ * This file is part of Cleanflight.
+ *
+ * Cleanflight 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.
+ *
+ * Cleanflight 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 Cleanflight. If not, see .
+ */
+
+#include
+#include
+
+#include
+
+#include "drivers/bus_spi.h"
+#include "drivers/io.h"
+
+// Bring a pin for possible CS line to pull-up state in preparation for
+// sequential initialization by relevant drivers.
+// Note that the pin is set to input for safety at this point.
+
+void spiPreInitCs(ioTag_t iotag)
+{
+ IO_t io = IOGetByTag(iotag);
+ if (io) {
+ IOConfigGPIO(io, IOCFG_IPU);
+ }
+}
diff --git a/src/main/drivers/bus_spi_hal.c b/src/main/drivers/bus_spi_hal.c
index 598559e66b..e33b943214 100644
--- a/src/main/drivers/bus_spi_hal.c
+++ b/src/main/drivers/bus_spi_hal.c
@@ -70,10 +70,10 @@
static spiDevice_t spiHardwareMap[] = {
- { .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), .af = GPIO_AF5_SPI1, .leadingEdge = false, .dmaIrqHandler = DMA2_ST3_HANDLER },
- { .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), .af = GPIO_AF5_SPI2, .leadingEdge = false, .dmaIrqHandler = DMA1_ST4_HANDLER },
- { .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), .af = GPIO_AF6_SPI3, .leadingEdge = false, .dmaIrqHandler = DMA1_ST7_HANDLER },
- { .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), .af = GPIO_AF5_SPI4, .leadingEdge = false, .dmaIrqHandler = DMA2_ST1_HANDLER }
+ { .dev = SPI1, .sck = IO_TAG(SPI1_SCK_PIN), .miso = IO_TAG(SPI1_MISO_PIN), .mosi = IO_TAG(SPI1_MOSI_PIN), .rcc = RCC_APB2(SPI1), .af = GPIO_AF5_SPI1, .leadingEdge = false, .dmaIrqHandler = DMA2_ST3_HANDLER },
+ { .dev = SPI2, .sck = IO_TAG(SPI2_SCK_PIN), .miso = IO_TAG(SPI2_MISO_PIN), .mosi = IO_TAG(SPI2_MOSI_PIN), .rcc = RCC_APB1(SPI2), .af = GPIO_AF5_SPI2, .leadingEdge = false, .dmaIrqHandler = DMA1_ST4_HANDLER },
+ { .dev = SPI3, .sck = IO_TAG(SPI3_SCK_PIN), .miso = IO_TAG(SPI3_MISO_PIN), .mosi = IO_TAG(SPI3_MOSI_PIN), .rcc = RCC_APB1(SPI3), .af = GPIO_AF6_SPI3, .leadingEdge = false, .dmaIrqHandler = DMA1_ST7_HANDLER },
+ { .dev = SPI4, .sck = IO_TAG(SPI4_SCK_PIN), .miso = IO_TAG(SPI4_MISO_PIN), .mosi = IO_TAG(SPI4_MOSI_PIN), .rcc = RCC_APB2(SPI4), .af = GPIO_AF5_SPI4, .leadingEdge = false, .dmaIrqHandler = DMA2_ST1_HANDLER }
};
SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
@@ -159,21 +159,11 @@ void spiInitDevice(SPIDevice device)
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_HIGH, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->af);
-
- if (spi->nss) {
- IOInit(IOGetByTag(spi->nss), OWNER_SPI_CS, RESOURCE_INDEX(device));
- IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
- }
#endif
#if defined(STM32F10X)
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_CFG);
-
- if (spi->nss) {
- IOInit(IOGetByTag(spi->nss), OWNER_SPI_CS, RESOURCE_INDEX(device));
- IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
- }
#endif
spiHardwareMap[device].hspi.Instance = spi->dev;
// Init SPI hardware
@@ -198,11 +188,7 @@ void spiInitDevice(SPIDevice device)
spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
}
- if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK)
- {
- if (spi->nss) {
- IOHi(IOGetByTag(spi->nss));
- }
+ if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) {
}
}
diff --git a/src/main/drivers/max7456.c b/src/main/drivers/max7456.c
index 11c69fe268..3ba0c60983 100644
--- a/src/main/drivers/max7456.c
+++ b/src/main/drivers/max7456.c
@@ -397,6 +397,7 @@ void max7456Init(const vcdProfile_t *pVcdProfile)
#endif
IOInit(max7456CsPin, OWNER_OSD_CS, 0);
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
+ IOHi(max7456CsPin);
spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD);
// force soft reset on Max7456
diff --git a/src/main/fc/fc_init.c b/src/main/fc/fc_init.c
index 53a72e11e2..0b2c5f069a 100644
--- a/src/main/fc/fc_init.c
+++ b/src/main/fc/fc_init.c
@@ -184,6 +184,46 @@ static IO_t busSwitchResetPin = IO_NONE;
}
#endif
+#ifdef USE_SPI
+// Pre-initialize all CS pins to input with pull-up.
+// It's sad that we can't do this with an initialized array,
+// since we will be taking care of configurable CS pins shortly.
+
+void spiPreInit(void)
+{
+#ifdef USE_ACC_SPI_MPU6000
+ spiPreInitCs(IO_TAG(MPU6000_CS_PIN));
+#endif
+#ifdef USE_ACC_SPI_MPU6500
+ spiPreInitCs(IO_TAG(MPU6500_CS_PIN));
+#endif
+#ifdef USE_GYRO_SPI_MPU9250
+ spiPreInitCs(IO_TAG(MPU9250_CS_PIN));
+#endif
+#ifdef USE_GYRO_SPI_ICM20689
+ spiPreInitCs(IO_TAG(ICM20689_CS_PIN));
+#endif
+#ifdef USE_ACCGYRO_BMI160
+ spiPreInitCs(IO_TAG(BMI160_CS_PIN));
+#endif
+#ifdef USE_MAX7456
+ spiPreInitCs(IO_TAG(MAX7456_SPI_CS_PIN));
+#endif
+#ifdef USE_SDCARD
+ spiPreInitCs(IO_TAG(SDCARD_SPI_CS_PIN));
+#endif
+#ifdef USE_BARO_SPI_BMP280
+ spiPreInitCs(IO_TAG(BMP280_CS_PIN));
+#endif
+#ifdef RTC6705_CS_PIN // XXX VTX_RTC6705? Should use USE_ format.
+ spiPreInitCs(IO_TAG(RTC6705_CS_PIN));
+#endif
+#ifdef M25P16_CS_PIN // XXX Should use USE_ format.
+ spiPreInitCs(IO_TAG(M25P16_CS_PIN));
+#endif
+}
+#endif
+
void init(void)
{
#ifdef USE_HAL_DRIVER
@@ -349,6 +389,9 @@ void init(void)
#else
#ifdef USE_SPI
+ // Initialize CS lines and keep them high
+ spiPreInit();
+
#ifdef USE_SPI_DEVICE_1
spiInit(SPIDEV_1);
#endif
diff --git a/src/main/target/CJMCU/initialisation.c b/src/main/target/CJMCU/initialisation.c
index 01986ce33e..4f6b7ecbe3 100644
--- a/src/main/target/CJMCU/initialisation.c
+++ b/src/main/target/CJMCU/initialisation.c
@@ -24,9 +24,12 @@
#include "drivers/bus_spi.h"
#include "io/serial.h"
+extern void spiPreInit(void); // XXX In fc/fc_init.c
+
void targetBusInit(void)
{
#if defined(USE_SPI) && defined(USE_SPI_DEVICE_1)
+ spiPreInit();
spiInit(SPIDEV_1);
#endif
diff --git a/src/main/target/NAZE/initialisation.c b/src/main/target/NAZE/initialisation.c
index 6f30d32602..c6b37d0544 100644
--- a/src/main/target/NAZE/initialisation.c
+++ b/src/main/target/NAZE/initialisation.c
@@ -25,9 +25,12 @@
#include "io/serial.h"
#include "hardware_revision.h"
+extern void spiPreInit(void); // XXX In fc/fc_init.c
+
void targetBusInit(void)
{
#ifdef USE_SPI
+ spiPreInit();
#ifdef USE_SPI_DEVICE_2
spiInit(SPIDEV_2);
#endif