diff --git a/make/mcu/STM32F1.mk b/make/mcu/STM32F1.mk
index 362a893e53..f8d0f09d1e 100644
--- a/make/mcu/STM32F1.mk
+++ b/make/mcu/STM32F1.mk
@@ -61,6 +61,7 @@ VCP_SRC = \
MCU_COMMON_SRC = \
drivers/adc_stm32f10x.c \
drivers/bus_i2c_stm32f10x.c \
+ drivers/bus_std_periph.c \
drivers/dma.c \
drivers/inverter.c \
drivers/light_ws2811strip_stdperiph.c \
diff --git a/make/mcu/STM32F3.mk b/make/mcu/STM32F3.mk
index 4d1bdbe798..08fad13beb 100644
--- a/make/mcu/STM32F3.mk
+++ b/make/mcu/STM32F3.mk
@@ -72,6 +72,7 @@ MCU_COMMON_SRC = \
target/system_stm32f30x.c \
drivers/adc_stm32f30x.c \
drivers/bus_i2c_stm32f30x.c \
+ drivers/bus_spi_stdperiph.c \
drivers/dma.c \
drivers/light_ws2811strip_stdperiph.c \
drivers/pwm_output_dshot.c \
diff --git a/make/mcu/STM32F4.mk b/make/mcu/STM32F4.mk
index 7574afa63e..199152f8e9 100644
--- a/make/mcu/STM32F4.mk
+++ b/make/mcu/STM32F4.mk
@@ -157,6 +157,7 @@ MCU_COMMON_SRC = \
drivers/accgyro/accgyro_mpu.c \
drivers/adc_stm32f4xx.c \
drivers/bus_i2c_stm32f10x.c \
+ drivers/bus_spi_stdperiph.c \
drivers/dma_stm32f4xx.c \
drivers/inverter.c \
drivers/light_ws2811strip_stdperiph.c \
diff --git a/make/mcu/STM32F7.mk b/make/mcu/STM32F7.mk
index 7433e6cca9..29cb420ec0 100644
--- a/make/mcu/STM32F7.mk
+++ b/make/mcu/STM32F7.mk
@@ -157,7 +157,6 @@ MCU_COMMON_SRC = \
drivers/serial_uart_hal.c
MCU_EXCLUDES = \
- drivers/bus_spi.c \
drivers/bus_i2c.c \
drivers/timer.c \
drivers/serial_uart.c
diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c
index 770ab52312..c3ac21f924 100644
--- a/src/main/drivers/bus_spi.c
+++ b/src/main/drivers/bus_spi.c
@@ -66,69 +66,6 @@ SPI_TypeDef *spiInstanceByDevice(SPIDevice device)
return spiDevice[device].dev;
}
-void spiInitDevice(SPIDevice device)
-{
- spiDevice_t *spi = &(spiDevice[device]);
-
-#ifdef SDCARD_SPI_INSTANCE
- if (spi->dev == SDCARD_SPI_INSTANCE) {
- spi->leadingEdge = true;
- }
-#endif
-#ifdef RX_SPI_INSTANCE
- if (spi->dev == RX_SPI_INSTANCE) {
- spi->leadingEdge = true;
- }
-#endif
-
- // Enable SPI clock
- RCC_ClockCmd(spi->rcc, ENABLE);
- RCC_ResetCmd(spi->rcc, ENABLE);
-
- IOInit(IOGetByTag(spi->sck), OWNER_SPI_SCK, RESOURCE_INDEX(device));
- IOInit(IOGetByTag(spi->miso), OWNER_SPI_MISO, RESOURCE_INDEX(device));
- IOInit(IOGetByTag(spi->mosi), OWNER_SPI_MOSI, RESOURCE_INDEX(device));
-
-#if defined(STM32F3) || defined(STM32F4)
- 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);
-#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);
-#endif
-
- // Init SPI hardware
- SPI_I2S_DeInit(spi->dev);
-
- SPI_InitTypeDef spiInit;
- spiInit.SPI_Mode = SPI_Mode_Master;
- spiInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
- spiInit.SPI_DataSize = SPI_DataSize_8b;
- spiInit.SPI_NSS = SPI_NSS_Soft;
- spiInit.SPI_FirstBit = SPI_FirstBit_MSB;
- spiInit.SPI_CRCPolynomial = 7;
- spiInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
-
- if (spi->leadingEdge) {
- spiInit.SPI_CPOL = SPI_CPOL_Low;
- spiInit.SPI_CPHA = SPI_CPHA_1Edge;
- } else {
- spiInit.SPI_CPOL = SPI_CPOL_High;
- spiInit.SPI_CPHA = SPI_CPHA_2Edge;
- }
-
-#ifdef STM32F303xC
- // Configure for 8-bit reads.
- SPI_RxFIFOThresholdConfig(spi->dev, SPI_RxFIFOThreshold_QF);
-#endif
-
- SPI_Init(spi->dev, &spiInit);
- SPI_Cmd(spi->dev, ENABLE);
-}
-
bool spiInit(SPIDevice device)
{
switch (device) {
@@ -149,7 +86,7 @@ bool spiInit(SPIDevice device)
break;
#endif
case SPIDEV_3:
-#if defined(USE_SPI_DEVICE_3) && (defined(STM32F303xC) || defined(STM32F4))
+#if defined(USE_SPI_DEVICE_3) && !defined(STM32F1)
spiInitDevice(device);
return true;
#else
@@ -176,81 +113,6 @@ uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance)
return spiDevice[device].errorCount;
}
-// return uint8_t value or -1 when failure
-uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
-{
- uint16_t spiTimeout = 1000;
-
- while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET)
- if ((spiTimeout--) == 0)
- return spiTimeoutUserCallback(instance);
-
-#ifdef STM32F303xC
- SPI_SendData8(instance, txByte);
-#else
- SPI_I2S_SendData(instance, txByte);
-#endif
- spiTimeout = 1000;
- while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET)
- if ((spiTimeout--) == 0)
- return spiTimeoutUserCallback(instance);
-
-#ifdef STM32F303xC
- return ((uint8_t)SPI_ReceiveData8(instance));
-#else
- return ((uint8_t)SPI_I2S_ReceiveData(instance));
-#endif
-}
-
-/**
- * Return true if the bus is currently in the middle of a transmission.
- */
-bool spiIsBusBusy(SPI_TypeDef *instance)
-{
-#ifdef STM32F303xC
- return SPI_GetTransmissionFIFOStatus(instance) != SPI_TransmissionFIFOStatus_Empty || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
-#else
- return SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
-#endif
-
-}
-
-bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
-{
- uint16_t spiTimeout = 1000;
-
- uint8_t b;
- instance->DR;
- while (len--) {
- b = txData ? *(txData++) : 0xFF;
- while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
- if ((spiTimeout--) == 0)
- return spiTimeoutUserCallback(instance);
- }
-#ifdef STM32F303xC
- SPI_SendData8(instance, b);
-#else
- SPI_I2S_SendData(instance, b);
-#endif
- spiTimeout = 1000;
- while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
- if ((spiTimeout--) == 0)
- return spiTimeoutUserCallback(instance);
- }
-#ifdef STM32F303xC
- b = SPI_ReceiveData8(instance);
-#else
- b = SPI_I2S_ReceiveData(instance);
-#endif
- if (rxData)
- *(rxData++) = b;
- }
-
- return true;
-}
-
-#include "build/debug.h"
-
bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxData, int length)
{
IOLo(bus->busdev_u.spi.csnPin);
@@ -259,28 +121,6 @@ bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxDa
return true;
}
-void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
-{
-#define BR_BITS ((BIT(5) | BIT(4) | BIT(3)))
-
-#if !(defined(STM32F1) || defined(STM32F3))
- // SPI2 and SPI3 are on APB1/AHB1 which PCLK is half that of APB2/AHB2.
-
- if (instance == SPI2 || instance == SPI3) {
- divisor /= 2; // Safe for divisor == 0 or 1
- }
-#endif
-
- SPI_Cmd(instance, DISABLE);
-
- const uint16_t tempRegister = (instance->CR1 & ~BR_BITS);
- instance->CR1 = tempRegister | (divisor ? ((ffs(divisor | 0x100) - 2) << 3) : 0);
-
- SPI_Cmd(instance, ENABLE);
-
-#undef BR_BITS
-}
-
uint16_t spiGetErrorCounter(SPI_TypeDef *instance)
{
SPIDevice device = spiDeviceByInstance(instance);
diff --git a/src/main/drivers/bus_spi_impl.h b/src/main/drivers/bus_spi_impl.h
index fe9ed35598..74c54725a6 100644
--- a/src/main/drivers/bus_spi_impl.h
+++ b/src/main/drivers/bus_spi_impl.h
@@ -70,3 +70,6 @@ typedef struct SPIDevice_s {
} spiDevice_t;
extern spiDevice_t spiDevice[SPIDEV_COUNT];
+
+void spiInitDevice(SPIDevice device);
+uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance);
diff --git a/src/main/drivers/bus_spi_ll.c b/src/main/drivers/bus_spi_ll.c
index 6e6e5b2993..b4a8ca8696 100644
--- a/src/main/drivers/bus_spi_ll.c
+++ b/src/main/drivers/bus_spi_ll.c
@@ -71,40 +71,6 @@ spiDevice_t spiDevice[SPIDEV_COUNT];
#define SPI_DEFAULT_TIMEOUT 10
-SPIDevice spiDeviceByInstance(SPI_TypeDef *instance)
-{
-#ifdef USE_SPI_DEVICE_1
- if (instance == SPI1)
- return SPIDEV_1;
-#endif
-
-#ifdef USE_SPI_DEVICE_2
- if (instance == SPI2)
- return SPIDEV_2;
-#endif
-
-#ifdef USE_SPI_DEVICE_3
- if (instance == SPI3)
- return SPIDEV_3;
-#endif
-
-#ifdef USE_SPI_DEVICE_4
- if (instance == SPI4)
- return SPIDEV_4;
-#endif
-
- return SPIINVALID;
-}
-
-SPI_TypeDef *spiInstanceByDevice(SPIDevice device)
-{
- if (device >= SPIDEV_COUNT) {
- return NULL;
- }
-
- return spiDevice[device].dev;
-}
-
void spiInitDevice(SPIDevice device)
{
spiDevice_t *spi = &(spiDevice[device]);
@@ -157,53 +123,6 @@ void spiInitDevice(SPIDevice device)
LL_SPI_Enable(spi->dev);
}
-bool spiInit(SPIDevice device)
-{
- switch (device) {
- case SPIINVALID:
- return false;
- case SPIDEV_1:
-#if defined(USE_SPI_DEVICE_1)
- spiInitDevice(device);
- return true;
-#else
- break;
-#endif
- case SPIDEV_2:
-#if defined(USE_SPI_DEVICE_2)
- spiInitDevice(device);
- return true;
-#else
- break;
-#endif
- case SPIDEV_3:
-#if defined(USE_SPI_DEVICE_3)
- spiInitDevice(device);
- return true;
-#else
- break;
-#endif
- case SPIDEV_4:
-#if defined(USE_SPI_DEVICE_4)
- spiInitDevice(device);
- return true;
-#else
- break;
-#endif
- }
- return false;
-}
-
-uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance)
-{
- SPIDevice device = spiDeviceByInstance(instance);
- if (device == SPIINVALID) {
- return -1;
- }
- spiDevice[device].errorCount++;
- return spiDevice[device].errorCount;
-}
-
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
{
uint16_t spiTimeout = 1000;
@@ -292,14 +211,6 @@ bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData,
return true;
}
-bool spiBusTransfer(const busDevice_t *bus, const uint8_t *txData, uint8_t *rxData, int length)
-{
- IOLo(bus->busdev_u.spi.csnPin);
- spiTransfer(bus->busdev_u.spi.instance, txData, rxData, length);
- IOHi(bus->busdev_u.spi.csnPin);
- return true;
-}
-
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
{
#if !(defined(STM32F1) || defined(STM32F3))
@@ -314,59 +225,4 @@ void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
LL_SPI_SetBaudRatePrescaler(instance, divisor ? (ffs(divisor | 0x100) - 2) << SPI_CR1_BR_Pos : 0);
LL_SPI_Enable(instance);
}
-
-uint16_t spiGetErrorCounter(SPI_TypeDef *instance)
-{
- SPIDevice device = spiDeviceByInstance(instance);
- if (device == SPIINVALID) {
- return 0;
- }
- return spiDevice[device].errorCount;
-}
-
-void spiResetErrorCounter(SPI_TypeDef *instance)
-{
- SPIDevice device = spiDeviceByInstance(instance);
- if (device != SPIINVALID) {
- spiDevice[device].errorCount = 0;
- }
-}
-
-bool spiBusWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data)
-{
- IOLo(bus->busdev_u.spi.csnPin);
- spiTransferByte(bus->busdev_u.spi.instance, reg);
- spiTransferByte(bus->busdev_u.spi.instance, data);
- IOHi(bus->busdev_u.spi.csnPin);
-
- return true;
-}
-
-bool spiBusReadRegisterBuffer(const busDevice_t *bus, uint8_t reg, uint8_t *data, uint8_t length)
-{
- IOLo(bus->busdev_u.spi.csnPin);
- spiTransferByte(bus->busdev_u.spi.instance, reg | 0x80); // read transaction
- spiTransfer(bus->busdev_u.spi.instance, NULL, data, length);
- IOHi(bus->busdev_u.spi.csnPin);
-
- return true;
-}
-
-uint8_t spiBusReadRegister(const busDevice_t *bus, uint8_t reg)
-{
- uint8_t data;
- IOLo(bus->busdev_u.spi.csnPin);
- spiTransferByte(bus->busdev_u.spi.instance, reg | 0x80); // read transaction
- spiTransfer(bus->busdev_u.spi.instance, NULL, &data, 1);
- IOHi(bus->busdev_u.spi.csnPin);
-
- return data;
-}
-
-void spiBusSetInstance(busDevice_t *bus, SPI_TypeDef *instance)
-{
- bus->bustype = BUSTYPE_SPI;
- bus->busdev_u.spi.instance = instance;
-}
-
#endif
diff --git a/src/main/drivers/bus_spi_stdperiph.c b/src/main/drivers/bus_spi_stdperiph.c
new file mode 100644
index 0000000000..22adb3a8a6
--- /dev/null
+++ b/src/main/drivers/bus_spi_stdperiph.c
@@ -0,0 +1,193 @@
+/*
+ * 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
+
+#ifdef USE_SPI
+
+#include "drivers/bus.h"
+#include "drivers/bus_spi.h"
+#include "drivers/bus_spi_impl.h"
+#include "drivers/exti.h"
+#include "drivers/io.h"
+#include "drivers/rcc.h"
+
+spiDevice_t spiDevice[SPIDEV_COUNT];
+
+void spiInitDevice(SPIDevice device)
+{
+ spiDevice_t *spi = &(spiDevice[device]);
+
+#ifdef SDCARD_SPI_INSTANCE
+ if (spi->dev == SDCARD_SPI_INSTANCE) {
+ spi->leadingEdge = true;
+ }
+#endif
+#ifdef RX_SPI_INSTANCE
+ if (spi->dev == RX_SPI_INSTANCE) {
+ spi->leadingEdge = true;
+ }
+#endif
+
+ // Enable SPI clock
+ RCC_ClockCmd(spi->rcc, ENABLE);
+ RCC_ResetCmd(spi->rcc, ENABLE);
+
+ IOInit(IOGetByTag(spi->sck), OWNER_SPI_SCK, RESOURCE_INDEX(device));
+ IOInit(IOGetByTag(spi->miso), OWNER_SPI_MISO, RESOURCE_INDEX(device));
+ IOInit(IOGetByTag(spi->mosi), OWNER_SPI_MOSI, RESOURCE_INDEX(device));
+
+#if defined(STM32F3) || defined(STM32F4)
+ 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);
+#elif 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);
+#else
+#error Undefined MCU architecture
+#endif
+
+ // Init SPI hardware
+ SPI_I2S_DeInit(spi->dev);
+
+ SPI_InitTypeDef spiInit;
+ spiInit.SPI_Mode = SPI_Mode_Master;
+ spiInit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
+ spiInit.SPI_DataSize = SPI_DataSize_8b;
+ spiInit.SPI_NSS = SPI_NSS_Soft;
+ spiInit.SPI_FirstBit = SPI_FirstBit_MSB;
+ spiInit.SPI_CRCPolynomial = 7;
+ spiInit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
+
+ if (spi->leadingEdge) {
+ spiInit.SPI_CPOL = SPI_CPOL_Low;
+ spiInit.SPI_CPHA = SPI_CPHA_1Edge;
+ } else {
+ spiInit.SPI_CPOL = SPI_CPOL_High;
+ spiInit.SPI_CPHA = SPI_CPHA_2Edge;
+ }
+
+#ifdef STM32F303xC
+ // Configure for 8-bit reads.
+ SPI_RxFIFOThresholdConfig(spi->dev, SPI_RxFIFOThreshold_QF);
+#endif
+
+ SPI_Init(spi->dev, &spiInit);
+ SPI_Cmd(spi->dev, ENABLE);
+}
+
+// return uint8_t value or -1 when failure
+uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t txByte)
+{
+ uint16_t spiTimeout = 1000;
+
+ while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET)
+ if ((spiTimeout--) == 0)
+ return spiTimeoutUserCallback(instance);
+
+#ifdef STM32F303xC
+ SPI_SendData8(instance, txByte);
+#else
+ SPI_I2S_SendData(instance, txByte);
+#endif
+ spiTimeout = 1000;
+ while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET)
+ if ((spiTimeout--) == 0)
+ return spiTimeoutUserCallback(instance);
+
+#ifdef STM32F303xC
+ return ((uint8_t)SPI_ReceiveData8(instance));
+#else
+ return ((uint8_t)SPI_I2S_ReceiveData(instance));
+#endif
+}
+
+/**
+ * Return true if the bus is currently in the middle of a transmission.
+ */
+bool spiIsBusBusy(SPI_TypeDef *instance)
+{
+#ifdef STM32F303xC
+ return SPI_GetTransmissionFIFOStatus(instance) != SPI_TransmissionFIFOStatus_Empty || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
+#else
+ return SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET || SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_BSY) == SET;
+#endif
+
+}
+
+bool spiTransfer(SPI_TypeDef *instance, const uint8_t *txData, uint8_t *rxData, int len)
+{
+ uint16_t spiTimeout = 1000;
+
+ uint8_t b;
+ instance->DR;
+ while (len--) {
+ b = txData ? *(txData++) : 0xFF;
+ while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_TXE) == RESET) {
+ if ((spiTimeout--) == 0)
+ return spiTimeoutUserCallback(instance);
+ }
+#ifdef STM32F303xC
+ SPI_SendData8(instance, b);
+#else
+ SPI_I2S_SendData(instance, b);
+#endif
+ spiTimeout = 1000;
+ while (SPI_I2S_GetFlagStatus(instance, SPI_I2S_FLAG_RXNE) == RESET) {
+ if ((spiTimeout--) == 0)
+ return spiTimeoutUserCallback(instance);
+ }
+#ifdef STM32F303xC
+ b = SPI_ReceiveData8(instance);
+#else
+ b = SPI_I2S_ReceiveData(instance);
+#endif
+ if (rxData)
+ *(rxData++) = b;
+ }
+
+ return true;
+}
+
+void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor)
+{
+#define BR_BITS ((BIT(5) | BIT(4) | BIT(3)))
+
+#if !(defined(STM32F1) || defined(STM32F3))
+ // SPI2 and SPI3 are on APB1/AHB1 which PCLK is half that of APB2/AHB2.
+
+ if (instance == SPI2 || instance == SPI3) {
+ divisor /= 2; // Safe for divisor == 0 or 1
+ }
+#endif
+
+ SPI_Cmd(instance, DISABLE);
+
+ const uint16_t tempRegister = (instance->CR1 & ~BR_BITS);
+ instance->CR1 = tempRegister | (divisor ? ((ffs(divisor | 0x100) - 2) << 3) : 0);
+
+ SPI_Cmd(instance, ENABLE);
+
+#undef BR_BITS
+}
+#endif