diff --git a/Makefile b/Makefile index e2b76957ed..30ebd2a888 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_pinconfig.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_pinconfig.c \ drivers/serial_escserial.c \ drivers/serial_pinconfig.c \ drivers/serial_uart_init.c \ @@ -1026,6 +1028,7 @@ SITLEXCLUDES = \ drivers/bus_spi.c \ drivers/bus_i2c.c \ drivers/bus_i2c_config.c \ + drivers/bus_spi_pinconfig.c \ drivers/dma.c \ drivers/pwm_output.c \ drivers/timer.c \ diff --git a/src/main/config/parameter_group_ids.h b/src/main/config/parameter_group_ids.h index e4b0bb3f59..ba3d202f21 100644 --- a/src/main/config/parameter_group_ids.h +++ b/src/main/config/parameter_group_ids.h @@ -107,7 +107,8 @@ #define PG_SONAR_CONFIG 516 #define PG_ESC_SENSOR_CONFIG 517 #define PG_I2C_CONFIG 518 -#define PG_BETAFLIGHT_END 518 +#define PG_SPI_PIN_CONFIG 519 +#define PG_BETAFLIGHT_END 519 // OSD configuration (subject to change) diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index b5aae9eca2..89e44f9fb8 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -17,89 +17,48 @@ #include #include +#include #include +#include "build/debug.h" + #include "drivers/bus_spi.h" +#include "drivers/bus_spi_impl.h" #include "drivers/exti.h" #include "drivers/io.h" -#include "io_impl.h" -#include "rcc.h" +#include "drivers/rcc.h" -/* for F30x processors */ -#if defined(STM32F303xC) -#ifndef GPIO_AF_SPI1 -#define GPIO_AF_SPI1 GPIO_AF_5 -#endif -#ifndef GPIO_AF_SPI2 -#define GPIO_AF_SPI2 GPIO_AF_5 -#endif -#ifndef GPIO_AF_SPI3 -#define GPIO_AF_SPI3 GPIO_AF_6 -#endif -#endif - -#ifndef SPI1_SCK_PIN -#define SPI1_NSS_PIN PA4 -#define SPI1_SCK_PIN PA5 -#define SPI1_MISO_PIN PA6 -#define SPI1_MOSI_PIN PA7 -#endif - -#ifndef SPI2_SCK_PIN -#define SPI2_NSS_PIN PB12 -#define SPI2_SCK_PIN PB13 -#define SPI2_MISO_PIN PB14 -#define SPI2_MOSI_PIN PB15 -#endif - -#ifndef SPI3_SCK_PIN -#define SPI3_NSS_PIN PA15 -#define SPI3_SCK_PIN PB3 -#define SPI3_MISO_PIN PB4 -#define SPI3_MOSI_PIN PB5 -#endif - -#ifndef SPI1_NSS_PIN -#define SPI1_NSS_PIN NONE -#endif -#ifndef SPI2_NSS_PIN -#define SPI2_NSS_PIN NONE -#endif -#ifndef SPI3_NSS_PIN -#define SPI3_NSS_PIN NONE -#endif - -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 }, -#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 }, -#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 } -#endif -}; +spiDevice_t spiDevice[SPIDEV_COUNT]; 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_3; +#endif return SPIINVALID; } void spiInitDevice(SPIDevice device) { - spiDevice_t *spi = &(spiHardwareMap[device]); + spiDevice_t *spi = &(spiDevice[device]); #ifdef SDCARD_SPI_INSTANCE if (spi->dev == SDCARD_SPI_INSTANCE) { @@ -121,24 +80,15 @@ void spiInitDevice(SPIDevice 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); + IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->sckAF); + IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_CFG, spi->misoAF); + IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->mosiAF); - 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 +118,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) @@ -218,8 +163,8 @@ uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance) SPIDevice device = spiDeviceByInstance(instance); if (device == SPIINVALID) return -1; - spiHardwareMap[device].errorCount++; - return spiHardwareMap[device].errorCount; + spiDevice[device].errorCount++; + return spiDevice[device].errorCount; } // return uint8_t value or -1 when failure @@ -303,51 +248,8 @@ void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor) SPI_Cmd(instance, DISABLE); - tempRegister = instance->CR1; - - switch (divisor) { - case 2: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_2; - break; - - case 4: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_4; - break; - - case 8: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_8; - break; - - case 16: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_16; - break; - - case 32: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_32; - break; - - case 64: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_64; - break; - - case 128: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_128; - break; - - case 256: - tempRegister &= BR_CLEAR_MASK; - tempRegister |= SPI_BaudRatePrescaler_256; - break; - } - - instance->CR1 = tempRegister; + tempRegister = (instance->CR1 & BR_CLEAR_MASK); + instance->CR1 = (tempRegister | ((ffs(divisor) - 1) << 3)); SPI_Cmd(instance, ENABLE); } @@ -357,12 +259,12 @@ uint16_t spiGetErrorCounter(SPI_TypeDef *instance) SPIDevice device = spiDeviceByInstance(instance); if (device == SPIINVALID) return 0; - return spiHardwareMap[device].errorCount; + return spiDevice[device].errorCount; } void spiResetErrorCounter(SPI_TypeDef *instance) { SPIDevice device = spiDeviceByInstance(instance); if (device != SPIINVALID) - spiHardwareMap[device].errorCount = 0; + spiDevice[device].errorCount = 0; } diff --git a/src/main/drivers/bus_spi.h b/src/main/drivers/bus_spi.h index 4b0bbf22e8..102320f6f3 100644 --- a/src/main/drivers/bus_spi.h +++ b/src/main/drivers/bus_spi.h @@ -69,22 +69,15 @@ typedef enum SPIDevice { SPIDEV_4 } SPIDevice; -typedef struct SPIDevice_s { - SPI_TypeDef *dev; - ioTag_t nss; - ioTag_t sck; - ioTag_t mosi; - ioTag_t miso; - rccPeriphTag_t rcc; - uint8_t af; - volatile uint16_t errorCount; - bool leadingEdge; -#if defined(STM32F7) - SPI_HandleTypeDef hspi; - DMA_HandleTypeDef hdma; - uint8_t dmaIrqHandler; +#if defined(STM32F1) +#define SPIDEV_COUNT 2 +#elif defined(STM32F3) || defined(STM32F4) +#define SPIDEV_COUNT 3 +#elif defined(STM32F7) +#define SPIDEV_COUNT 4 +#else +#define SPIDEV_COUNT 4 #endif -} spiDevice_t; bool spiInit(SPIDevice device); void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor); @@ -101,3 +94,11 @@ SPIDevice spiDeviceByInstance(SPI_TypeDef *instance); SPI_HandleTypeDef* spiHandleByInstance(SPI_TypeDef *instance); DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channel, SPI_TypeDef *Instance, uint8_t *pData, uint16_t Size); #endif + +typedef struct spiPinConfig_s { + ioTag_t ioTagSck[SPIDEV_COUNT]; + ioTag_t ioTagMiso[SPIDEV_COUNT]; + ioTag_t ioTagMosi[SPIDEV_COUNT]; +} spiPinConfig_t; + +void spiPinConfigure(void); diff --git a/src/main/drivers/bus_spi_hal.c b/src/main/drivers/bus_spi_hal.c index 598559e66b..3ba5031d1d 100644 --- a/src/main/drivers/bus_spi_hal.c +++ b/src/main/drivers/bus_spi_hal.c @@ -21,112 +21,73 @@ #include #include "drivers/bus_spi.h" -#include "dma.h" +#include "drivers/bus_spi_impl.h" +#include "drivers/dma.h" #include "drivers/io.h" -#include "io_impl.h" #include "drivers/nvic.h" -#include "rcc.h" +#include "drivers/rcc.h" -#ifndef SPI1_SCK_PIN -#define SPI1_NSS_PIN PA4 -#define SPI1_SCK_PIN PA5 -#define SPI1_MISO_PIN PA6 -#define SPI1_MOSI_PIN PA7 -#endif - -#ifndef SPI2_SCK_PIN -#define SPI2_NSS_PIN PB12 -#define SPI2_SCK_PIN PB13 -#define SPI2_MISO_PIN PB14 -#define SPI2_MOSI_PIN PB15 -#endif - -#ifndef SPI3_SCK_PIN -#define SPI3_NSS_PIN PA15 -#define SPI3_SCK_PIN PB3 -#define SPI3_MISO_PIN PB4 -#define SPI3_MOSI_PIN PB5 -#endif - -#ifndef SPI4_SCK_PIN -#define SPI4_NSS_PIN PA15 -#define SPI4_SCK_PIN PB3 -#define SPI4_MISO_PIN PB4 -#define SPI4_MOSI_PIN PB5 -#endif - -#ifndef SPI1_NSS_PIN -#define SPI1_NSS_PIN NONE -#endif -#ifndef SPI2_NSS_PIN -#define SPI2_NSS_PIN NONE -#endif -#ifndef SPI3_NSS_PIN -#define SPI3_NSS_PIN NONE -#endif -#ifndef SPI4_NSS_PIN -#define SPI4_NSS_PIN NONE -#endif - - -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 } -}; +spiDevice_t spiDevice[SPIDEV_COUNT]; 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_HandleTypeDef* spiHandleByInstance(SPI_TypeDef *instance) { - return &spiHardwareMap[spiDeviceByInstance(instance)].hspi; + return &spiDevice[spiDeviceByInstance(instance)].hspi; } DMA_HandleTypeDef* dmaHandleByInstance(SPI_TypeDef *instance) { - return &spiHardwareMap[spiDeviceByInstance(instance)].hdma; + return &spiDevice[spiDeviceByInstance(instance)].hdma; } void SPI1_IRQHandler(void) { - HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_1].hspi); + HAL_SPI_IRQHandler(&spiDevice[SPIDEV_1].hspi); } void SPI2_IRQHandler(void) { - HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_2].hspi); + HAL_SPI_IRQHandler(&spiDevice[SPIDEV_2].hspi); } void SPI3_IRQHandler(void) { - HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_3].hspi); + HAL_SPI_IRQHandler(&spiDevice[SPIDEV_3].hspi); } void SPI4_IRQHandler(void) { - HAL_SPI_IRQHandler(&spiHardwareMap[SPIDEV_4].hspi); + HAL_SPI_IRQHandler(&spiDevice[SPIDEV_4].hspi); } void spiInitDevice(SPIDevice device) { - spiDevice_t *spi = &(spiHardwareMap[device]); + spiDevice_t *spi = &(spiDevice[device]); #ifdef SDCARD_SPI_INSTANCE if (spi->dev == SDCARD_SPI_INSTANCE) { @@ -154,55 +115,42 @@ void spiInitDevice(SPIDevice device) #if defined(STM32F3) || defined(STM32F4) || defined(STM32F7) if(spi->leadingEdge == true) - IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_LOW, spi->af); + IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_LOW, spi->sckAF); else - 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); - } + IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG_HIGH, spi->sckAF); + IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->misoAF); + IOConfigGPIOAF(IOGetByTag(spi->mosi), SPI_IO_AF_CFG, spi->mosiAF); #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; + spiDevice[device].hspi.Instance = spi->dev; // Init SPI hardware - HAL_SPI_DeInit(&spiHardwareMap[device].hspi); + HAL_SPI_DeInit(&spiDevice[device].hspi); - spiHardwareMap[device].hspi.Init.Mode = SPI_MODE_MASTER; - spiHardwareMap[device].hspi.Init.Direction = SPI_DIRECTION_2LINES; - spiHardwareMap[device].hspi.Init.DataSize = SPI_DATASIZE_8BIT; - spiHardwareMap[device].hspi.Init.NSS = SPI_NSS_SOFT; - spiHardwareMap[device].hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; - spiHardwareMap[device].hspi.Init.CRCPolynomial = 7; - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; - spiHardwareMap[device].hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; - spiHardwareMap[device].hspi.Init.TIMode = SPI_TIMODE_DISABLED; + spiDevice[device].hspi.Init.Mode = SPI_MODE_MASTER; + spiDevice[device].hspi.Init.Direction = SPI_DIRECTION_2LINES; + spiDevice[device].hspi.Init.DataSize = SPI_DATASIZE_8BIT; + spiDevice[device].hspi.Init.NSS = SPI_NSS_SOFT; + spiDevice[device].hspi.Init.FirstBit = SPI_FIRSTBIT_MSB; + spiDevice[device].hspi.Init.CRCPolynomial = 7; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + spiDevice[device].hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + spiDevice[device].hspi.Init.TIMode = SPI_TIMODE_DISABLED; if (spi->leadingEdge) { - spiHardwareMap[device].hspi.Init.CLKPolarity = SPI_POLARITY_LOW; - spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_1EDGE; + spiDevice[device].hspi.Init.CLKPolarity = SPI_POLARITY_LOW; + spiDevice[device].hspi.Init.CLKPhase = SPI_PHASE_1EDGE; } else { - spiHardwareMap[device].hspi.Init.CLKPolarity = SPI_POLARITY_HIGH; - spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE; + spiDevice[device].hspi.Init.CLKPolarity = SPI_POLARITY_HIGH; + spiDevice[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE; } - if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) + if (HAL_SPI_Init(&spiDevice[device].hspi) == HAL_OK) { - if (spi->nss) { - IOHi(IOGetByTag(spi->nss)); - } } } @@ -249,8 +197,8 @@ uint32_t spiTimeoutUserCallback(SPI_TypeDef *instance) SPIDevice device = spiDeviceByInstance(instance); if (device == SPIINVALID) return -1; - spiHardwareMap[device].errorCount++; - return spiHardwareMap[device].errorCount; + spiDevice[device].errorCount++; + return spiDevice[device].errorCount; } // return uint8_t value or -1 when failure @@ -266,7 +214,7 @@ uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in) bool spiIsBusBusy(SPI_TypeDef *instance) { SPIDevice device = spiDeviceByInstance(instance); - if(spiHardwareMap[device].hspi.State == HAL_SPI_STATE_BUSY) + if(spiDevice[device].hspi.State == HAL_SPI_STATE_BUSY) return true; else return false; @@ -281,15 +229,15 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len if(!out) // Tx only { - status = HAL_SPI_Transmit(&spiHardwareMap[device].hspi, (uint8_t *)in, len, SPI_DEFAULT_TIMEOUT); + status = HAL_SPI_Transmit(&spiDevice[device].hspi, (uint8_t *)in, len, SPI_DEFAULT_TIMEOUT); } else if(!in) // Rx only { - status = HAL_SPI_Receive(&spiHardwareMap[device].hspi, out, len, SPI_DEFAULT_TIMEOUT); + status = HAL_SPI_Receive(&spiDevice[device].hspi, out, len, SPI_DEFAULT_TIMEOUT); } else // Tx and Rx { - status = HAL_SPI_TransmitReceive(&spiHardwareMap[device].hspi, (uint8_t *)in, out, len, SPI_DEFAULT_TIMEOUT); + status = HAL_SPI_TransmitReceive(&spiDevice[device].hspi, (uint8_t *)in, out, len, SPI_DEFAULT_TIMEOUT); } if( status != HAL_OK) @@ -302,45 +250,45 @@ bool spiTransfer(SPI_TypeDef *instance, uint8_t *out, const uint8_t *in, int len void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor) { SPIDevice device = spiDeviceByInstance(instance); - if (HAL_SPI_DeInit(&spiHardwareMap[device].hspi) == HAL_OK) + if (HAL_SPI_DeInit(&spiDevice[device].hspi) == HAL_OK) { } switch (divisor) { case 2: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; break; case 4: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; break; case 8: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; break; case 16: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; break; case 32: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; break; case 64: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; break; case 128: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; break; case 256: - spiHardwareMap[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + spiDevice[device].hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; break; } - if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) + if (HAL_SPI_Init(&spiDevice[device].hspi) == HAL_OK) { } } @@ -350,21 +298,21 @@ uint16_t spiGetErrorCounter(SPI_TypeDef *instance) SPIDevice device = spiDeviceByInstance(instance); if (device == SPIINVALID) return 0; - return spiHardwareMap[device].errorCount; + return spiDevice[device].errorCount; } void spiResetErrorCounter(SPI_TypeDef *instance) { SPIDevice device = spiDeviceByInstance(instance); if (device != SPIINVALID) - spiHardwareMap[device].errorCount = 0; + spiDevice[device].errorCount = 0; } void dmaSPIIRQHandler(dmaChannelDescriptor_t* descriptor) { SPIDevice device = descriptor->userParam; if (device != SPIINVALID) - HAL_DMA_IRQHandler(&spiHardwareMap[device].hdma); + HAL_DMA_IRQHandler(&spiDevice[device].hdma); } @@ -372,35 +320,35 @@ DMA_HandleTypeDef* spiSetDMATransmit(DMA_Stream_TypeDef *Stream, uint32_t Channe { SPIDevice device = spiDeviceByInstance(Instance); - spiHardwareMap[device].hdma.Instance = Stream; - spiHardwareMap[device].hdma.Init.Channel = Channel; - spiHardwareMap[device].hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; - spiHardwareMap[device].hdma.Init.PeriphInc = DMA_PINC_DISABLE; - spiHardwareMap[device].hdma.Init.MemInc = DMA_MINC_ENABLE; - spiHardwareMap[device].hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; - spiHardwareMap[device].hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; - spiHardwareMap[device].hdma.Init.Mode = DMA_NORMAL; - spiHardwareMap[device].hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; - spiHardwareMap[device].hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; - spiHardwareMap[device].hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; - spiHardwareMap[device].hdma.Init.MemBurst = DMA_MBURST_SINGLE; - spiHardwareMap[device].hdma.Init.Priority = DMA_PRIORITY_LOW; + spiDevice[device].hdma.Instance = Stream; + spiDevice[device].hdma.Init.Channel = Channel; + spiDevice[device].hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; + spiDevice[device].hdma.Init.PeriphInc = DMA_PINC_DISABLE; + spiDevice[device].hdma.Init.MemInc = DMA_MINC_ENABLE; + spiDevice[device].hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + spiDevice[device].hdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + spiDevice[device].hdma.Init.Mode = DMA_NORMAL; + spiDevice[device].hdma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + spiDevice[device].hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_1QUARTERFULL; + spiDevice[device].hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; + spiDevice[device].hdma.Init.MemBurst = DMA_MBURST_SINGLE; + spiDevice[device].hdma.Init.Priority = DMA_PRIORITY_LOW; - HAL_DMA_DeInit(&spiHardwareMap[device].hdma); - HAL_DMA_Init(&spiHardwareMap[device].hdma); + HAL_DMA_DeInit(&spiDevice[device].hdma); + HAL_DMA_Init(&spiDevice[device].hdma); - __HAL_DMA_ENABLE(&spiHardwareMap[device].hdma); - __HAL_SPI_ENABLE(&spiHardwareMap[device].hspi); + __HAL_DMA_ENABLE(&spiDevice[device].hdma); + __HAL_SPI_ENABLE(&spiDevice[device].hspi); /* Associate the initialized DMA handle to the spi handle */ - __HAL_LINKDMA(&spiHardwareMap[device].hspi, hdmatx, spiHardwareMap[device].hdma); + __HAL_LINKDMA(&spiDevice[device].hspi, hdmatx, spiDevice[device].hdma); // DMA TX Interrupt - dmaSetHandler(spiHardwareMap[device].dmaIrqHandler, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)device); + dmaSetHandler(spiDevice[device].dmaIrqHandler, dmaSPIIRQHandler, NVIC_BUILD_PRIORITY(3, 0), (uint32_t)device); //HAL_CLEANCACHE(pData,Size); // And Transmit - HAL_SPI_Transmit_DMA(&spiHardwareMap[device].hspi, pData, Size); + HAL_SPI_Transmit_DMA(&spiDevice[device].hspi, pData, Size); - return &spiHardwareMap[device].hdma; + return &spiDevice[device].hdma; } diff --git a/src/main/drivers/bus_spi_impl.h b/src/main/drivers/bus_spi_impl.h new file mode 100644 index 0000000000..b2373293fe --- /dev/null +++ b/src/main/drivers/bus_spi_impl.h @@ -0,0 +1,63 @@ +/* + * 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 . + */ + +#pragma once + +#if defined(STM32F1) || defined(STM32F3) || defined(STM32F4) +#define MAX_SPI_PIN_SEL 2 +#else +#define MAX_SPI_PIN_SEL 4 +#endif + +typedef struct spiPinDef_s { + ioTag_t pin; + uint8_t af; +} spiPinDef_t; + +typedef struct spiHardware_s { + SPIDevice device; + SPI_TypeDef *reg; + spiPinDef_t sckPins[MAX_SPI_PIN_SEL]; + spiPinDef_t misoPins[MAX_SPI_PIN_SEL]; + spiPinDef_t mosiPins[MAX_SPI_PIN_SEL]; + rccPeriphTag_t rcc; +#if defined(USE_HAL_DRIVER) + uint8_t dmaIrqHandler; +#endif +} spiHardware_t; + +extern const spiHardware_t spiHardware[]; + +typedef struct SPIDevice_s { + SPI_TypeDef *dev; + ioTag_t sck; + ioTag_t miso; + ioTag_t mosi; + uint8_t sckAF; + uint8_t misoAF; + uint8_t mosiAF; + rccPeriphTag_t rcc; + volatile uint16_t errorCount; + bool leadingEdge; +#if defined(USE_HAL_DRIVER) + SPI_HandleTypeDef hspi; + DMA_HandleTypeDef hdma; + uint8_t dmaIrqHandler; +#endif +} spiDevice_t; + +extern spiDevice_t spiDevice[SPIDEV_COUNT]; diff --git a/src/main/drivers/bus_spi_pinconfig.c b/src/main/drivers/bus_spi_pinconfig.c new file mode 100644 index 0000000000..372e8a131d --- /dev/null +++ b/src/main/drivers/bus_spi_pinconfig.c @@ -0,0 +1,383 @@ +/* + * 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 + +#include "build/debug.h" + +#include "drivers/bus_spi.h" +#include "drivers/bus_spi_impl.h" +#include "drivers/dma.h" +#include "drivers/exti.h" +#include "drivers/io.h" +#include "drivers/rcc.h" + +#include "config/parameter_group.h" +#include "config/parameter_group_ids.h" + +// Pin defaults +#ifndef SPI1_SCK_PIN +#define SPI1_NSS_PIN PA4 +#define SPI1_SCK_PIN PA5 +#define SPI1_MISO_PIN PA6 +#define SPI1_MOSI_PIN PA7 +#endif + +#ifndef SPI2_SCK_PIN +#define SPI2_NSS_PIN PB12 +#define SPI2_SCK_PIN PB13 +#define SPI2_MISO_PIN PB14 +#define SPI2_MOSI_PIN PB15 +#endif + +#ifndef SPI3_SCK_PIN +#define SPI3_NSS_PIN PA15 +#define SPI3_SCK_PIN PB3 +#define SPI3_MISO_PIN PB4 +#define SPI3_MOSI_PIN PB5 +#endif + +#ifndef SPI1_NSS_PIN +#define SPI1_NSS_PIN NONE +#endif +#ifndef SPI2_NSS_PIN +#define SPI2_NSS_PIN NONE +#endif +#ifndef SPI3_NSS_PIN +#define SPI3_NSS_PIN NONE +#endif + +PG_DECLARE(spiPinConfig_t, spiPinConfig); + +PG_REGISTER_WITH_RESET_FN(spiPinConfig_t, spiPinConfig, PG_SPI_PIN_CONFIG, 0); + +typedef struct spiDefaultConfig_s { + SPIDevice device; + ioTag_t sck; + ioTag_t miso; + ioTag_t mosi; +} spiDefaultConfig_t; + +const spiDefaultConfig_t spiDefaultConfig[] = { +#ifdef USE_SPI_DEVICE_1 + { SPIDEV_1, IO_TAG(SPI1_SCK_PIN), IO_TAG(SPI1_MISO_PIN), IO_TAG(SPI1_MOSI_PIN) }, +#endif +#ifdef USE_SPI_DEVICE_2 + { SPIDEV_2, IO_TAG(SPI2_SCK_PIN), IO_TAG(SPI2_MISO_PIN), IO_TAG(SPI2_MOSI_PIN) }, +#endif +#ifdef USE_SPI_DEVICE_3 + { SPIDEV_3, IO_TAG(SPI3_SCK_PIN), IO_TAG(SPI3_MISO_PIN), IO_TAG(SPI3_MOSI_PIN) }, +#endif +#ifdef USE_SPI_DEVICE_4 + { SPIDEV_4, IO_TAG(SPI4_SCK_PIN), IO_TAG(SPI4_MISO_PIN), IO_TAG(SPI4_MOSI_PIN) }, +#endif +}; + +void pgResetFn_spiPinConfig(spiPinConfig_t *spiPinConfig) +{ + memset(spiPinConfig, 0, sizeof(*spiPinConfig)); + + for (size_t i = 0 ; i < ARRAYLEN(spiDefaultConfig) ; i++) { + const spiDefaultConfig_t *defconf = &spiDefaultConfig[i]; + spiPinConfig->ioTagSck[defconf->device] = defconf->sck; + spiPinConfig->ioTagMiso[defconf->device] = defconf->miso; + spiPinConfig->ioTagMosi[defconf->device] = defconf->mosi; + } +} + + +const spiHardware_t spiHardware[] = { +#ifdef STM32F1 + // Remapping is not supported and corresponding lines are commented out. + // There also is some errata that may prevent these assignments from working: + // 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 + { + .device = SPIDEV_1, + .reg = SPI1, + .sckPins = { + { DEFIO_TAG_E(PA5), 0 }, + // { DEFIO_TAG_E(PB3), GPIO_AF }, + }, + .misoPins = { + { DEFIO_TAG_E(PA6), 0 }, + // { DEFIO_TAG_E(PB4), GPIO_AF }, + }, + .mosiPins = { + { DEFIO_TAG_E(PA7), 0 }, + // { DEFIO_TAG_E(PB5), GPIO_AF }, + }, + .rcc = RCC_APB2(SPI1), + }, + { + .device = SPIDEV_2, + .reg = SPI2, + .sckPins = { + { DEFIO_TAG_E(PB13), 0 }, + // { DEFIO_TAG_E(PB3), GPIO_AF }, + }, + .misoPins = { + { DEFIO_TAG_E(PB14), 0 }, + // { DEFIO_TAG_E(PB4), GPIO_AF }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB15), 0 }, + // { DEFIO_TAG_E(PB5), GPIO_AF }, + }, + .rcc = RCC_APB1(SPI2), + }, +#endif +#ifdef STM32F3 + +#ifndef GPIO_AF_SPI1 +#define GPIO_AF_SPI1 GPIO_AF_5 +#endif +#ifndef GPIO_AF_SPI2 +#define GPIO_AF_SPI2 GPIO_AF_5 +#endif +#ifndef GPIO_AF_SPI3 +#define GPIO_AF_SPI3 GPIO_AF_6 +#endif + + { + .device = SPIDEV_1, + .reg = SPI1, + .sckPins = { + { DEFIO_TAG_E(PA5), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB3), GPIO_AF_SPI1 }, + }, + .misoPins = { + { DEFIO_TAG_E(PA6), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB4), GPIO_AF_SPI1 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PA7), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB5), GPIO_AF_SPI1 }, + }, + .rcc = RCC_APB2(SPI1), + }, + { + .device = SPIDEV_2, + .reg = SPI2, + .sckPins = { + { DEFIO_TAG_E(PB13), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PB3), GPIO_AF_SPI2 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB14), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PB4), GPIO_AF_SPI2 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB15), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PB5), GPIO_AF_SPI2 }, + }, + .rcc = RCC_APB1(SPI2), + }, + { + .device = SPIDEV_3, + .reg = SPI3, + .sckPins = { + { DEFIO_TAG_E(PB3), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC10), GPIO_AF_SPI3 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB4), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC11), GPIO_AF_SPI3 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB5), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC12), GPIO_AF_SPI3 }, + }, + .rcc = RCC_APB1(SPI3), + }, +#endif +#ifdef STM32F4 + { + .device = SPIDEV_1, + .reg = SPI1, + .sckPins = { + { DEFIO_TAG_E(PA5), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB3), GPIO_AF_SPI1 }, + }, + .misoPins = { + { DEFIO_TAG_E(PA6), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB4), GPIO_AF_SPI1 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PA7), GPIO_AF_SPI1 }, + { DEFIO_TAG_E(PB5), GPIO_AF_SPI1 }, + }, + .rcc = RCC_APB2(SPI1), + }, + { + .device = SPIDEV_2, + .reg = SPI2, + .sckPins = { + { DEFIO_TAG_E(PB10), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PB13), GPIO_AF_SPI2 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB14), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PC2), GPIO_AF_SPI2 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB15), GPIO_AF_SPI2 }, + { DEFIO_TAG_E(PC3), GPIO_AF_SPI2 }, + }, + .rcc = RCC_APB1(SPI2), + }, + { + .device = SPIDEV_3, + .reg = SPI3, + .sckPins = { + { DEFIO_TAG_E(PB3), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC10), GPIO_AF_SPI3 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB4), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC11), GPIO_AF_SPI3 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB5), GPIO_AF_SPI3 }, + { DEFIO_TAG_E(PC12), GPIO_AF_SPI3 }, + }, + .rcc = RCC_APB1(SPI3), + }, +#endif +#ifdef STM32F7 + { + .device = SPIDEV_1, + .reg = SPI1, + .sckPins = { + { DEFIO_TAG_E(PA5), GPIO_AF5_SPI1 }, + { DEFIO_TAG_E(PB3), GPIO_AF5_SPI1 }, + }, + .misoPins = { + { DEFIO_TAG_E(PA6), GPIO_AF5_SPI1 }, + { DEFIO_TAG_E(PB4), GPIO_AF5_SPI1 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PA7), GPIO_AF5_SPI1 }, + { DEFIO_TAG_E(PB5), GPIO_AF5_SPI1 }, + }, + .rcc = RCC_APB2(SPI1), + .dmaIrqHandler = DMA2_ST3_HANDLER, + }, + { + .device = SPIDEV_2, + .reg = SPI2, + .sckPins = { + { DEFIO_TAG_E(PA9), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PB10), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PB13), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PD3), GPIO_AF5_SPI2 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB14), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PC2), GPIO_AF5_SPI2 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB15), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PC1), GPIO_AF5_SPI2 }, + { DEFIO_TAG_E(PC3), GPIO_AF5_SPI2 }, + }, + .rcc = RCC_APB1(SPI2), + .dmaIrqHandler = DMA1_ST4_HANDLER, + }, + { + .device = SPIDEV_3, + .reg = SPI3, + .sckPins = { + { DEFIO_TAG_E(PB3), GPIO_AF6_SPI3 }, + { DEFIO_TAG_E(PC10), GPIO_AF6_SPI3 }, + }, + .misoPins = { + { DEFIO_TAG_E(PB4), GPIO_AF6_SPI3 }, + { DEFIO_TAG_E(PC11), GPIO_AF6_SPI3 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PB2), GPIO_AF7_SPI3 }, + { DEFIO_TAG_E(PB5), GPIO_AF6_SPI3 }, + { DEFIO_TAG_E(PC12), GPIO_AF6_SPI3 }, + { DEFIO_TAG_E(PD6), GPIO_AF5_SPI3 }, + }, + .rcc = RCC_APB1(SPI3), + .dmaIrqHandler = DMA1_ST7_HANDLER, + }, + { + .device = SPIDEV_4, + .reg = SPI4, + .sckPins = { + { DEFIO_TAG_E(PE2), GPIO_AF5_SPI4 }, + { DEFIO_TAG_E(PE12), GPIO_AF6_SPI3 }, + }, + .misoPins = { + { DEFIO_TAG_E(PE5), GPIO_AF5_SPI4 }, + { DEFIO_TAG_E(PE13), GPIO_AF5_SPI4 }, + }, + .mosiPins = { + { DEFIO_TAG_E(PE6), GPIO_AF5_SPI4 }, + { DEFIO_TAG_E(PE14), GPIO_AF5_SPI4 }, + }, + .rcc = RCC_APB2(SPI4), + .dmaIrqHandler = DMA2_ST1_HANDLER, + }, +#endif +}; + +void spiPinConfigure(void) +{ + const spiPinConfig_t *pConfig = spiPinConfig(); + + for (size_t hwindex = 0 ; hwindex < ARRAYLEN(spiDefaultConfig) ; hwindex++) { + const spiHardware_t *hw = &spiHardware[hwindex]; + + if (!hw->reg) { + continue; + } + + int device = hw->device; + spiDevice_t *pDev = &spiDevice[device]; + + for (int pindex = 0 ; pindex < MAX_SPI_PIN_SEL ; pindex++) { + if (pConfig->ioTagSck[device] == hw->sckPins[pindex].pin) { + pDev->sck = hw->sckPins[pindex].pin; + pDev->sckAF = hw->sckPins[pindex].af; + } + if (pConfig->ioTagMiso[device] == hw->misoPins[pindex].pin) { + pDev->miso = hw->misoPins[pindex].pin; + pDev->misoAF = hw->misoPins[pindex].af; + } + if (pConfig->ioTagMosi[device] == hw->mosiPins[pindex].pin) { + pDev->mosi = hw->mosiPins[pindex].pin; + pDev->mosiAF = hw->mosiPins[pindex].af; + } + } + + if (pDev->sck && pDev->miso && pDev->mosi) { + pDev->dev = hw->reg; + pDev->rcc = hw->rcc; + pDev->leadingEdge = false; // XXX Should be part of transfer context +#ifdef USE_HAL_DRIVER + pDev->dmaIrqHandler = hw->dmaIrqHandler; +#endif + } + } +} diff --git a/src/main/fc/cli.c b/src/main/fc/cli.c index b2adcfbbee..535feeaacd 100755 --- a/src/main/fc/cli.c +++ b/src/main/fc/cli.c @@ -56,6 +56,7 @@ extern uint8_t __config_end; #include "drivers/accgyro/accgyro.h" #include "drivers/buf_writer.h" #include "drivers/bus_i2c.h" +#include "drivers/bus_spi.h" #include "drivers/compass/compass.h" #include "drivers/display.h" #include "drivers/dma.h" @@ -2755,6 +2756,15 @@ const cliResourceValue_t resourceTable[] = { { OWNER_I2C_SCL, PG_I2C_CONFIG, offsetof(i2cConfig_t, ioTagScl[0]), I2CDEV_COUNT }, { OWNER_I2C_SDA, PG_I2C_CONFIG, offsetof(i2cConfig_t, ioTagSda[0]), I2CDEV_COUNT }, #endif +#ifdef USE_SPEKTRUM_BIND + { OWNER_RX_BIND, PG_RX_CONFIG, offsetof(rxConfig_t, spektrum_bind_pin_override_ioTag), 0 }, + { OWNER_RX_BIND_PLUG, PG_RX_CONFIG, offsetof(rxConfig_t, spektrum_bind_plug_ioTag), 0 }, +#endif +#ifdef USE_SPI + { OWNER_SPI_SCK, PG_SPI_PIN_CONFIG, offsetof(spiPinConfig_t, ioTagSck[0]), SPIDEV_COUNT }, + { OWNER_SPI_MISO, PG_SPI_PIN_CONFIG, offsetof(spiPinConfig_t, ioTagMiso[0]), SPIDEV_COUNT }, + { OWNER_SPI_MOSI, PG_SPI_PIN_CONFIG, offsetof(spiPinConfig_t, ioTagMosi[0]), SPIDEV_COUNT }, +#endif }; static ioTag_t *getIoTag(const cliResourceValue_t value, uint8_t index) diff --git a/src/main/fc/fc_init.c b/src/main/fc/fc_init.c index 53a72e11e2..65a921a09b 100644 --- a/src/main/fc/fc_init.c +++ b/src/main/fc/fc_init.c @@ -349,6 +349,8 @@ void init(void) #else #ifdef USE_SPI + spiPinConfigure(); + #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..51218fa1d2 100644 --- a/src/main/target/CJMCU/initialisation.c +++ b/src/main/target/CJMCU/initialisation.c @@ -26,8 +26,11 @@ void targetBusInit(void) { -#if defined(USE_SPI) && defined(USE_SPI_DEVICE_1) +#ifdef USE_SPI + spiPinConfigure(); +#ifdef USE_SPI_DEVICE_1 spiInit(SPIDEV_1); +#endif #endif if (!doesConfigurationUsePort(SERIAL_PORT_USART3)) { diff --git a/src/main/target/COLIBRI_RACE/target.c b/src/main/target/COLIBRI_RACE/target.c index 12d4cdeebc..a6a1e1f109 100644 --- a/src/main/target/COLIBRI_RACE/target.c +++ b/src/main/target/COLIBRI_RACE/target.c @@ -21,6 +21,7 @@ #include #include "drivers/bus_i2c.h" +#include "drivers/bus_spi.h" #include "drivers/io.h" #include "drivers/dma.h" #include "drivers/timer.h" @@ -53,8 +54,14 @@ const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = { #ifdef USE_BST void targetBusInit(void) { +#ifdef USE_SPI + spiPinConfigure(); +#ifdef USE_SPI_DEVICE_1 + spiInit(SPIDEV_1); +#endif +#endif + i2cHardwareConfigure(); bstInit(BST_DEVICE); } #endif - diff --git a/src/main/target/NAZE/initialisation.c b/src/main/target/NAZE/initialisation.c index 6f30d32602..2d80333a45 100644 --- a/src/main/target/NAZE/initialisation.c +++ b/src/main/target/NAZE/initialisation.c @@ -28,6 +28,7 @@ void targetBusInit(void) { #ifdef USE_SPI + spiPinConfigure(); #ifdef USE_SPI_DEVICE_2 spiInit(SPIDEV_2); #endif