Merge pull request #3321 from jflyper/bfdev-set-spi-cs-initial-high-2

Preset CS lines for SPI devices initial high
This commit is contained in:
Martin Budden 2017-06-23 10:36:16 +01:00 committed by GitHub
commit cca6d1ad6a
15 changed files with 124 additions and 42 deletions

View File

@ -681,6 +681,7 @@ COMMON_SRC = \
drivers/bus_i2c_config.c \ drivers/bus_i2c_config.c \
drivers/bus_i2c_soft.c \ drivers/bus_i2c_soft.c \
drivers/bus_spi.c \ drivers/bus_spi.c \
drivers/bus_spi_config.c \
drivers/bus_spi_soft.c \ drivers/bus_spi_soft.c \
drivers/buttons.c \ drivers/buttons.c \
drivers/display.c \ drivers/display.c \
@ -901,6 +902,7 @@ SPEED_OPTIMISED_SRC := $(SPEED_OPTIMISED_SRC) \
SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \ SIZE_OPTIMISED_SRC := $(SIZE_OPTIMISED_SRC) \
drivers/bus_i2c_config.c \ drivers/bus_i2c_config.c \
drivers/bus_spi_config.c \
drivers/serial_escserial.c \ drivers/serial_escserial.c \
drivers/serial_pinconfig.c \ drivers/serial_pinconfig.c \
drivers/serial_uart_init.c \ drivers/serial_uart_init.c \
@ -1027,9 +1029,10 @@ F7EXCLUDES = \
SITLEXCLUDES = \ SITLEXCLUDES = \
drivers/adc.c \ drivers/adc.c \
drivers/bus_spi.c \
drivers/bus_i2c.c \ drivers/bus_i2c.c \
drivers/bus_i2c_config.c \ drivers/bus_i2c_config.c \
drivers/bus_spi.c \
drivers/bus_spi_config.c \
drivers/dma.c \ drivers/dma.c \
drivers/pwm_output.c \ drivers/pwm_output.c \
drivers/timer.c \ drivers/timer.c \

View File

@ -103,6 +103,7 @@ bool bmi160Detect(const busDevice_t *bus)
return true; return true;
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0); IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG); IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
IOHi(bus->spi.csnPin);
spiSetDivisor(BMI160_SPI_INSTANCE, BMI160_SPI_DIVISOR); spiSetDivisor(BMI160_SPI_INSTANCE, BMI160_SPI_DIVISOR);

View File

@ -69,6 +69,7 @@ static void icm20689SpiInit(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0); IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG); IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
IOHi(bus->spi.csnPin);
spiSetDivisor(ICM20689_SPI_INSTANCE, SPI_CLOCK_STANDARD); spiSetDivisor(ICM20689_SPI_INSTANCE, SPI_CLOCK_STANDARD);

View File

@ -155,6 +155,7 @@ bool mpu6000SpiDetect(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0); IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG); IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
IOHi(bus->spi.csnPin);
spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON);

View File

@ -77,6 +77,7 @@ static void mpu6500SpiInit(const busDevice_t *bus)
IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0); IOInit(bus->spi.csnPin, OWNER_MPU_CS, 0);
IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG); IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG);
IOHi(bus->spi.csnPin);
spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST); spiSetDivisor(MPU6500_SPI_INSTANCE, SPI_CLOCK_FAST);

View File

@ -72,14 +72,14 @@
static spiDevice_t spiHardwareMap[] = { static spiDevice_t spiHardwareMap[] = {
#if defined(STM32F1) #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 = 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, .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 = 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 #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 = 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, .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 = 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 #endif
#if defined(STM32F3) || defined(STM32F4) #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 #endif
}; };
@ -124,21 +124,11 @@ void spiInitDevice(SPIDevice device)
IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->sck), SPI_IO_AF_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), 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->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 #endif
#if defined(STM32F10X) #if defined(STM32F10X)
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG); IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG); IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_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 #endif
// Init SPI hardware // Init SPI hardware
@ -168,11 +158,6 @@ void spiInitDevice(SPIDevice device)
SPI_Init(spi->dev, &spiInit); SPI_Init(spi->dev, &spiInit);
SPI_Cmd(spi->dev, ENABLE); SPI_Cmd(spi->dev, ENABLE);
if (spi->nss) {
// Drive NSS high to disable connected SPI device.
IOHi(IOGetByTag(spi->nss));
}
} }
bool spiInit(SPIDevice device) bool spiInit(SPIDevice device)

View File

@ -71,7 +71,6 @@ typedef enum SPIDevice {
typedef struct SPIDevice_s { typedef struct SPIDevice_s {
SPI_TypeDef *dev; SPI_TypeDef *dev;
ioTag_t nss;
ioTag_t sck; ioTag_t sck;
ioTag_t mosi; ioTag_t mosi;
ioTag_t miso; ioTag_t miso;
@ -86,6 +85,7 @@ typedef struct SPIDevice_s {
#endif #endif
} spiDevice_t; } spiDevice_t;
void spiPreInitCs(ioTag_t iotag);
bool spiInit(SPIDevice device); bool spiInit(SPIDevice device);
void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor); void spiSetDivisor(SPI_TypeDef *instance, uint16_t divisor);
uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in); uint8_t spiTransferByte(SPI_TypeDef *instance, uint8_t in);

View File

@ -0,0 +1,37 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdbool.h>
#include <stdint.h>
#include <platform.h>
#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) {
IOInit(io, OWNER_SPI_PREINIT, 0);
IOConfigGPIO(io, IOCFG_IPU);
}
}

View File

@ -70,10 +70,10 @@
static spiDevice_t spiHardwareMap[] = { 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 = 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, .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 = 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, .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 = 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, .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 = 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) 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->sck), SPI_IO_AF_SCK_CFG_HIGH, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->af); IOConfigGPIOAF(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG, spi->af);
IOConfigGPIOAF(IOGetByTag(spi->mosi), 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));
IOConfigGPIO(IOGetByTag(spi->nss), SPI_IO_CS_CFG);
}
#endif #endif
#if defined(STM32F10X) #if defined(STM32F10X)
IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG); IOConfigGPIO(IOGetByTag(spi->sck), SPI_IO_AF_SCK_CFG);
IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG); IOConfigGPIO(IOGetByTag(spi->miso), SPI_IO_AF_MISO_CFG);
IOConfigGPIO(IOGetByTag(spi->mosi), SPI_IO_AF_MOSI_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 #endif
spiHardwareMap[device].hspi.Instance = spi->dev; spiHardwareMap[device].hspi.Instance = spi->dev;
// Init SPI hardware // Init SPI hardware
@ -198,11 +188,7 @@ void spiInitDevice(SPIDevice device)
spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE; spiHardwareMap[device].hspi.Init.CLKPhase = SPI_PHASE_2EDGE;
} }
if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) if (HAL_SPI_Init(&spiHardwareMap[device].hspi) == HAL_OK) {
{
if (spi->nss) {
IOHi(IOGetByTag(spi->nss));
}
} }
} }

View File

@ -397,6 +397,7 @@ void max7456Init(const vcdProfile_t *pVcdProfile)
#endif #endif
IOInit(max7456CsPin, OWNER_OSD_CS, 0); IOInit(max7456CsPin, OWNER_OSD_CS, 0);
IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG); IOConfigGPIO(max7456CsPin, SPI_IO_CS_CFG);
IOHi(max7456CsPin);
spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD); spiSetDivisor(MAX7456_SPI_INSTANCE, SPI_CLOCK_STANDARD);
// force soft reset on Max7456 // force soft reset on Max7456

View File

@ -61,6 +61,7 @@ const char * const ownerNames[OWNER_TOTAL_COUNT] = {
"LED_STRIP", "LED_STRIP",
"TRANSPONDER", "TRANSPONDER",
"VTX", "VTX",
"COMPASS_CS" "COMPASS_CS",
"SPI_PREINIT",
}; };

View File

@ -62,6 +62,7 @@ typedef enum {
OWNER_TRANSPONDER, OWNER_TRANSPONDER,
OWNER_VTX, OWNER_VTX,
OWNER_COMPASS_CS, OWNER_COMPASS_CS,
OWNER_SPI_PREINIT,
OWNER_TOTAL_COUNT OWNER_TOTAL_COUNT
} resourceOwner_e; } resourceOwner_e;

View File

@ -185,6 +185,61 @@ static IO_t busSwitchResetPin = IO_NONE;
} }
#endif #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_GYRO_L3GD20
spiPreInitCs(IO_TAG(L3GD20_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 USE_BARO_SPI_MS5611
spiPreInitCs(IO_TAG(MS5611_CS_PIN));
#endif
#ifdef USE_MAG_SPI_HMC5883
spiPreInitCs(IO_TAG(HMC5883_CS_PIN));
#endif
#ifdef USE_MAG_SPI_AK8963
spiPreInitCs(IO_TAG(AK8963_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
#if defined(USE_RX_SPI) && !defined(USE_RX_SOFTSPI)
spiPreInitCs(IO_TAG(RX_NSS_PIN));
#endif
}
#endif
void init(void) void init(void)
{ {
#ifdef USE_HAL_DRIVER #ifdef USE_HAL_DRIVER
@ -352,6 +407,9 @@ void init(void)
#else #else
#ifdef USE_SPI #ifdef USE_SPI
// Initialize CS lines and keep them high
spiPreInit();
#ifdef USE_SPI_DEVICE_1 #ifdef USE_SPI_DEVICE_1
spiInit(SPIDEV_1); spiInit(SPIDEV_1);
#endif #endif

View File

@ -24,9 +24,12 @@
#include "drivers/bus_spi.h" #include "drivers/bus_spi.h"
#include "io/serial.h" #include "io/serial.h"
extern void spiPreInit(void); // XXX In fc/fc_init.c
void targetBusInit(void) void targetBusInit(void)
{ {
#if defined(USE_SPI) && defined(USE_SPI_DEVICE_1) #if defined(USE_SPI) && defined(USE_SPI_DEVICE_1)
spiPreInit();
spiInit(SPIDEV_1); spiInit(SPIDEV_1);
#endif #endif

View File

@ -25,9 +25,12 @@
#include "io/serial.h" #include "io/serial.h"
#include "hardware_revision.h" #include "hardware_revision.h"
extern void spiPreInit(void); // XXX In fc/fc_init.c
void targetBusInit(void) void targetBusInit(void)
{ {
#ifdef USE_SPI #ifdef USE_SPI
spiPreInit();
#ifdef USE_SPI_DEVICE_2 #ifdef USE_SPI_DEVICE_2
spiInit(SPIDEV_2); spiInit(SPIDEV_2);
#endif #endif