From 8df87bc47d3b0c837aaedfd0f0d4b947e8beaffd Mon Sep 17 00:00:00 2001 From: Martin Budden Date: Thu, 29 Jun 2017 05:40:31 +0100 Subject: [PATCH] Make SPI read and write register generic --- src/main/drivers/accgyro/accgyro_mpu.c | 6 +- .../drivers/accgyro/accgyro_spi_mpu6000.c | 61 ++++++------------- .../drivers/accgyro/accgyro_spi_mpu6000.h | 3 - src/main/drivers/bus_spi.c | 25 +++++++- src/main/drivers/bus_spi.h | 6 +- src/main/drivers/bus_spi_hal.c | 26 +++++++- 6 files changed, 74 insertions(+), 53 deletions(-) diff --git a/src/main/drivers/accgyro/accgyro_mpu.c b/src/main/drivers/accgyro/accgyro_mpu.c index 35e80f2060..3127c011a0 100644 --- a/src/main/drivers/accgyro/accgyro_mpu.c +++ b/src/main/drivers/accgyro/accgyro_mpu.c @@ -30,6 +30,7 @@ #include "common/utils.h" #include "drivers/bus_i2c.h" +#include "drivers/bus_spi.h" #include "drivers/exti.h" #include "drivers/io.h" #include "drivers/nvic.h" @@ -233,14 +234,15 @@ static bool detectSPISensorsAndUpdateDetectionResult(gyroDev_t *gyro) { UNUSED(gyro); // since there are FCs which have gyro on I2C but other devices on SPI #ifdef USE_GYRO_SPI_MPU6000 + gyro->bus.spi.instance = MPU6000_SPI_INSTANCE; #ifdef MPU6000_CS_PIN gyro->bus.spi.csnPin = gyro->bus.spi.csnPin == IO_NONE ? IOGetByTag(IO_TAG(MPU6000_CS_PIN)) : gyro->bus.spi.csnPin; #endif if (mpu6000SpiDetect(&gyro->bus)) { gyro->mpuDetectionResult.sensor = MPU_60x0_SPI; gyro->mpuConfiguration.gyroReadXRegister = MPU_RA_GYRO_XOUT_H; - gyro->mpuConfiguration.readFn = mpu6000SpiReadRegister; - gyro->mpuConfiguration.writeFn = mpu6000SpiWriteRegister; + gyro->mpuConfiguration.readFn = spiReadRegister; + gyro->mpuConfiguration.writeFn = spiWriteRegister; return true; } #endif diff --git a/src/main/drivers/accgyro/accgyro_spi_mpu6000.c b/src/main/drivers/accgyro/accgyro_spi_mpu6000.c index 3ce84e4a50..006f32eebd 100644 --- a/src/main/drivers/accgyro/accgyro_spi_mpu6000.c +++ b/src/main/drivers/accgyro/accgyro_spi_mpu6000.c @@ -99,42 +99,19 @@ static bool mpuSpi6000InitDone = false; #define MPU6000_REV_D9 0x59 #define MPU6000_REV_D10 0x5A -#define DISABLE_MPU6000(spiCsnPin) IOHi(spiCsnPin) -#define ENABLE_MPU6000(spiCsnPin) IOLo(spiCsnPin) - -bool mpu6000SpiWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data) -{ - ENABLE_MPU6000(bus->spi.csnPin); - spiTransferByte(MPU6000_SPI_INSTANCE, reg); - spiTransferByte(MPU6000_SPI_INSTANCE, data); - DISABLE_MPU6000(bus->spi.csnPin); - - return true; -} - -bool mpu6000SpiReadRegister(const busDevice_t *bus, uint8_t reg, uint8_t length, uint8_t *data) -{ - ENABLE_MPU6000(bus->spi.csnPin); - spiTransferByte(MPU6000_SPI_INSTANCE, reg | 0x80); // read transaction - spiTransfer(MPU6000_SPI_INSTANCE, data, NULL, length); - DISABLE_MPU6000(bus->spi.csnPin); - - return true; -} - void mpu6000SpiGyroInit(gyroDev_t *gyro) { mpuGyroInit(gyro); mpu6000AccAndGyroInit(gyro); - spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); + spiSetDivisor(gyro->bus.spi.instance, SPI_CLOCK_INITIALIZATON); // Accel and Gyro DLPF Setting - mpu6000SpiWriteRegister(&gyro->bus, MPU6000_CONFIG, gyro->lpf); + spiWriteRegister(&gyro->bus, MPU6000_CONFIG, gyro->lpf); delayMicroseconds(1); - spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_FAST); // 18 MHz SPI clock + spiSetDivisor(gyro->bus.spi.instance, SPI_CLOCK_FAST); // 18 MHz SPI clock mpuGyroRead(gyro); @@ -157,14 +134,14 @@ bool mpu6000SpiDetect(const busDevice_t *bus) IOConfigGPIO(bus->spi.csnPin, SPI_IO_CS_CFG); IOHi(bus->spi.csnPin); - spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); + spiSetDivisor(bus->spi.instance, SPI_CLOCK_INITIALIZATON); - mpu6000SpiWriteRegister(bus, MPU_RA_PWR_MGMT_1, BIT_H_RESET); + spiWriteRegister(bus, MPU_RA_PWR_MGMT_1, BIT_H_RESET); do { delay(150); - mpu6000SpiReadRegister(bus, MPU_RA_WHO_AM_I, 1, &in); + spiReadRegister(bus, MPU_RA_WHO_AM_I, 1, &in); if (in == MPU6000_WHO_AM_I_CONST) { break; } @@ -173,7 +150,7 @@ bool mpu6000SpiDetect(const busDevice_t *bus) } } while (attemptsRemaining--); - mpu6000SpiReadRegister(bus, MPU_RA_PRODUCT_ID, 1, &in); + spiReadRegister(bus, MPU_RA_PRODUCT_ID, 1, &in); /* look for a product ID we recognise */ @@ -203,48 +180,48 @@ static void mpu6000AccAndGyroInit(gyroDev_t *gyro) return; } - spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_INITIALIZATON); + spiSetDivisor(gyro->bus.spi.instance, SPI_CLOCK_INITIALIZATON); // Device Reset - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_1, BIT_H_RESET); + spiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_1, BIT_H_RESET); delay(150); - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_SIGNAL_PATH_RESET, BIT_GYRO | BIT_ACC | BIT_TEMP); + spiWriteRegister(&gyro->bus, MPU_RA_SIGNAL_PATH_RESET, BIT_GYRO | BIT_ACC | BIT_TEMP); delay(150); // Clock Source PPL with Z axis gyro reference - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ); + spiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ); delayMicroseconds(15); // Disable Primary I2C Interface - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_USER_CTRL, BIT_I2C_IF_DIS); + spiWriteRegister(&gyro->bus, MPU_RA_USER_CTRL, BIT_I2C_IF_DIS); delayMicroseconds(15); - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_2, 0x00); + spiWriteRegister(&gyro->bus, MPU_RA_PWR_MGMT_2, 0x00); delayMicroseconds(15); // Accel Sample Rate 1kHz // Gyroscope Output Rate = 1kHz when the DLPF is enabled - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_SMPLRT_DIV, gyroMPU6xxxGetDividerDrops(gyro)); + spiWriteRegister(&gyro->bus, MPU_RA_SMPLRT_DIV, gyroMPU6xxxGetDividerDrops(gyro)); delayMicroseconds(15); // Gyro +/- 1000 DPS Full Scale - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3); + spiWriteRegister(&gyro->bus, MPU_RA_GYRO_CONFIG, INV_FSR_2000DPS << 3); delayMicroseconds(15); // Accel +/- 8 G Full Scale - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_ACCEL_CONFIG, INV_FSR_8G << 3); + spiWriteRegister(&gyro->bus, MPU_RA_ACCEL_CONFIG, INV_FSR_8G << 3); delayMicroseconds(15); - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0); // INT_ANYRD_2CLEAR + spiWriteRegister(&gyro->bus, MPU_RA_INT_PIN_CFG, 0 << 7 | 0 << 6 | 0 << 5 | 1 << 4 | 0 << 3 | 0 << 2 | 0 << 1 | 0 << 0); // INT_ANYRD_2CLEAR delayMicroseconds(15); #ifdef USE_MPU_DATA_READY_SIGNAL - mpu6000SpiWriteRegister(&gyro->bus, MPU_RA_INT_ENABLE, MPU_RF_DATA_RDY_EN); + spiWriteRegister(&gyro->bus, MPU_RA_INT_ENABLE, MPU_RF_DATA_RDY_EN); delayMicroseconds(15); #endif - spiSetDivisor(MPU6000_SPI_INSTANCE, SPI_CLOCK_FAST); + spiSetDivisor(gyro->bus.spi.instance, SPI_CLOCK_FAST); delayMicroseconds(1); mpuSpi6000InitDone = true; diff --git a/src/main/drivers/accgyro/accgyro_spi_mpu6000.h b/src/main/drivers/accgyro/accgyro_spi_mpu6000.h index 7eb9b6918c..8435cebad0 100644 --- a/src/main/drivers/accgyro/accgyro_spi_mpu6000.h +++ b/src/main/drivers/accgyro/accgyro_spi_mpu6000.h @@ -21,6 +21,3 @@ bool mpu6000SpiDetect(const busDevice_t *bus); bool mpu6000SpiAccDetect(accDev_t *acc); bool mpu6000SpiGyroDetect(gyroDev_t *gyro); - -bool mpu6000SpiWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data); -bool mpu6000SpiReadRegister(const busDevice_t *bus, uint8_t reg, uint8_t length, uint8_t *data); diff --git a/src/main/drivers/bus_spi.c b/src/main/drivers/bus_spi.c index eb0c2fdbc6..9022ecde14 100644 --- a/src/main/drivers/bus_spi.c +++ b/src/main/drivers/bus_spi.c @@ -20,11 +20,12 @@ #include +#include "drivers/bus.h" #include "drivers/bus_spi.h" #include "drivers/exti.h" #include "drivers/io.h" -#include "io_impl.h" -#include "rcc.h" +#include "drivers/io_impl.h" +#include "drivers/rcc.h" /* for F30x processors */ #if defined(STM32F303xC) @@ -351,3 +352,23 @@ void spiResetErrorCounter(SPI_TypeDef *instance) if (device != SPIINVALID) spiHardwareMap[device].errorCount = 0; } + +bool spiWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data) +{ + IOLo(bus->spi.csnPin); + spiTransferByte(bus->spi.instance, reg); + spiTransferByte(bus->spi.instance, data); + IOHi(bus->spi.csnPin); + + return true; +} + +bool spiReadRegister(const busDevice_t *bus, uint8_t reg, uint8_t length, uint8_t *data) +{ + IOLo(bus->spi.csnPin); + spiTransferByte(bus->spi.instance, reg | 0x80); // read transaction + spiTransfer(bus->spi.instance, data, NULL, length); + IOHi(bus->spi.csnPin); + + return true; +} diff --git a/src/main/drivers/bus_spi.h b/src/main/drivers/bus_spi.h index 9803ae77d9..9e825abadc 100644 --- a/src/main/drivers/bus_spi.h +++ b/src/main/drivers/bus_spi.h @@ -18,7 +18,8 @@ #pragma once #include "drivers/io_types.h" -#include "rcc_types.h" +#include "drivers/bus.h" +#include "drivers/rcc_types.h" #if defined(STM32F4) || defined(STM32F3) #define SPI_IO_AF_CFG IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_NOPULL) @@ -101,3 +102,6 @@ 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 + +bool spiWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data); +bool spiReadRegister(const busDevice_t *bus, uint8_t reg, uint8_t length, uint8_t *data); diff --git a/src/main/drivers/bus_spi_hal.c b/src/main/drivers/bus_spi_hal.c index e33b943214..467d713483 100644 --- a/src/main/drivers/bus_spi_hal.c +++ b/src/main/drivers/bus_spi_hal.c @@ -21,11 +21,11 @@ #include #include "drivers/bus_spi.h" -#include "dma.h" +#include "drivers/dma.h" #include "drivers/io.h" -#include "io_impl.h" +#include "drivers/io_impl.h" #include "drivers/nvic.h" -#include "rcc.h" +#include "drivers/rcc.h" #ifndef SPI1_SCK_PIN #define SPI1_NSS_PIN PA4 @@ -346,6 +346,26 @@ void spiResetErrorCounter(SPI_TypeDef *instance) spiHardwareMap[device].errorCount = 0; } +bool spiWriteRegister(const busDevice_t *bus, uint8_t reg, uint8_t data) +{ + IOLo(bus->spi.csnPin); + spiTransferByte(bus->spi.instance, reg); + spiTransferByte(bus->spi.instance, data); + IOHi(bus->spi.csnPin); + + return true; +} + +bool spiReadRegister(const busDevice_t *bus, uint8_t reg, uint8_t length, uint8_t *data) +{ + IOLo(bus->spi.csnPin); + spiTransferByte(bus->spi.instance, reg | 0x80); // read transaction + spiTransfer(bus->spi.instance, data, NULL, length); + IOHi(bus->spi.csnPin); + + return true; +} + void dmaSPIIRQHandler(dmaChannelDescriptor_t* descriptor) { SPIDevice device = descriptor->userParam;