diff --git a/make/source.mk b/make/source.mk
index b58b9bba02..e7f9dd4677 100644
--- a/make/source.mk
+++ b/make/source.mk
@@ -232,6 +232,7 @@ SPEED_OPTIMISED_SRC := $(SPEED_OPTIMISED_SRC) \
drivers/accgyro/accgyro_mpu3050.c \
drivers/accgyro/accgyro_spi_bmi160.c \
drivers/accgyro/accgyro_spi_bmi270.c \
+ drivers/accgyro/accgyro_spi_bmi088.c \
drivers/accgyro/accgyro_spi_lsm6dso.c \
drivers/accgyro_legacy/accgyro_adxl345.c \
drivers/accgyro_legacy/accgyro_bma280.c \
diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c
index c8f60ca06c..36f8977375 100644
--- a/src/main/cli/cli.c
+++ b/src/main/cli/cli.c
@@ -5097,6 +5097,7 @@ const cliResourceValue_t resourceTable[] = {
#endif
DEFW( OWNER_GYRO_EXTI, PG_GYRO_DEVICE_CONFIG, gyroDeviceConfig_t, extiTag, MAX_GYRODEV_COUNT ),
DEFW( OWNER_GYRO_CS, PG_GYRO_DEVICE_CONFIG, gyroDeviceConfig_t, csnTag, MAX_GYRODEV_COUNT ),
+ DEFW( OWNER_ACC_CS, PG_GYRO_DEVICE_CONFIG, gyroDeviceConfig_t, csnAccTag, MAX_GYRODEV_COUNT),
#ifdef USE_USB_DETECT
DEFS( OWNER_USB_DETECT, PG_USB_CONFIG, usbDev_t, detectPin ),
#endif
diff --git a/src/main/cli/settings.c b/src/main/cli/settings.c
index 561485e7d9..fcf05c53f3 100644
--- a/src/main/cli/settings.c
+++ b/src/main/cli/settings.c
@@ -136,14 +136,14 @@
const char * const lookupTableAccHardware[] = {
"AUTO", "NONE", "ADXL345", "MPU6050", "MMA8452", "BMA280", "LSM303DLHC",
"MPU6000", "MPU6500", "MPU9250", "ICM20601", "ICM20602", "ICM20608G", "ICM20649", "ICM20689", "ICM42605", "ICM42688P",
- "BMI160", "BMI270", "LSM6DSO", "FAKE"
+ "BMI160", "BMI270", "LSM6DSO", "BMI088", "FAKE"
};
// sync with gyroHardware_e
const char * const lookupTableGyroHardware[] = {
"AUTO", "NONE", "MPU6050", "L3G4200D", "MPU3050", "L3GD20",
"MPU6000", "MPU6500", "MPU9250", "ICM20601", "ICM20602", "ICM20608G", "ICM20649", "ICM20689", "ICM42605", "ICM42688P",
- "BMI160", "BMI270", "LSM6SDO", "FAKE"
+ "BMI160", "BMI270", "LSM6SDO", "BMI088", "FAKE"
};
#if defined(USE_SENSOR_NAMES) || defined(USE_BARO)
diff --git a/src/main/drivers/accgyro/accgyro.h b/src/main/drivers/accgyro/accgyro.h
index f93d0e784c..c9cb0796f8 100644
--- a/src/main/drivers/accgyro/accgyro.h
+++ b/src/main/drivers/accgyro/accgyro.h
@@ -59,6 +59,7 @@ typedef enum {
GYRO_BMI160,
GYRO_BMI270,
GYRO_LSM6DSO,
+ GYRO_BMI088,
GYRO_FAKE
} gyroHardware_e;
@@ -75,6 +76,7 @@ typedef enum {
typedef enum {
GYRO_RATE_1_kHz,
GYRO_RATE_1100_Hz,
+ GYRO_RATE_2000_Hz,
GYRO_RATE_3200_Hz,
GYRO_RATE_6400_Hz,
GYRO_RATE_6664_Hz,
@@ -99,6 +101,7 @@ typedef struct gyroDev_s {
sensorGyroReadDataFuncPtr temperatureFn; // read temperature if available
extiCallbackRec_t exti;
extDevice_t dev;
+ IO_t csnAccPin;
float scale; // scalefactor
float gyroZero[XYZ_AXIS_COUNT];
float gyroADC[XYZ_AXIS_COUNT]; // gyro data after calibration and alignment
@@ -143,6 +146,7 @@ typedef struct accDev_s {
sensor_align_e accAlign;
bool dataReady;
gyroDev_t *gyro;
+ extDevice_t dev;
bool acc_high_fsr;
char revisionCode; // a revision code for the sensor, if known
uint8_t filler[2];
diff --git a/src/main/drivers/accgyro/accgyro_mpu.c b/src/main/drivers/accgyro/accgyro_mpu.c
index abcd2c0875..de21f797af 100644
--- a/src/main/drivers/accgyro/accgyro_mpu.c
+++ b/src/main/drivers/accgyro/accgyro_mpu.c
@@ -48,6 +48,7 @@
#include "drivers/accgyro/accgyro_mpu6500.h"
#include "drivers/accgyro/accgyro_spi_bmi160.h"
#include "drivers/accgyro/accgyro_spi_bmi270.h"
+#include "drivers/accgyro/accgyro_spi_bmi088.h"
#include "drivers/accgyro/accgyro_spi_icm20649.h"
#include "drivers/accgyro/accgyro_spi_icm20689.h"
#include "drivers/accgyro/accgyro_spi_icm426xx.h"
@@ -360,6 +361,9 @@ static gyroSpiDetectFn_t gyroSpiDetectFnTable[] = {
#ifdef USE_ACCGYRO_BMI270
bmi270Detect,
#endif
+#ifdef USE_ACCGYRO_SPI_BMI088
+ bmi088SpiDetect,
+#endif
#if defined(USE_GYRO_SPI_ICM42605) || defined(USE_GYRO_SPI_ICM42688P)
icm426xxSpiDetect,
#endif
@@ -384,6 +388,14 @@ static bool detectSPISensorsAndUpdateDetectionResult(gyroDev_t *gyro, const gyro
IOConfigGPIO(gyro->dev.busType_u.spi.csnPin, SPI_IO_CS_CFG);
IOHi(gyro->dev.busType_u.spi.csnPin); // Ensure device is disabled, important when two devices are on the same bus.
+ // for BMI088 which has two CS pins
+ if(config->csnAccTag) {
+ gyro->csnAccPin = IOGetByTag(config->csnAccTag);
+ IOInit(gyro->csnAccPin, OWNER_ACC_CS, RESOURCE_INDEX(config->index));
+ IOConfigGPIO(gyro->csnAccPin, SPI_IO_CS_CFG);
+ IOHi(gyro->csnAccPin); // Ensure device is disabled, important when two devices are on the same bus.
+ }
+
uint8_t sensor = MPU_NONE;
// Allow 100ms before attempting to access gyro's SPI bus
@@ -409,6 +421,9 @@ static bool detectSPISensorsAndUpdateDetectionResult(gyroDev_t *gyro, const gyro
// Detection failed, disable CS pin again
spiPreinitByTag(config->csnTag);
+ if(config->csnAccTag) {
+ spiPreinitByTag(config->csnAccTag);
+ }
return false;
}
diff --git a/src/main/drivers/accgyro/accgyro_mpu.h b/src/main/drivers/accgyro/accgyro_mpu.h
index 0077dcc268..9d35b496e0 100644
--- a/src/main/drivers/accgyro/accgyro_mpu.h
+++ b/src/main/drivers/accgyro/accgyro_mpu.h
@@ -204,6 +204,7 @@ typedef enum {
BMI_270_SPI,
LSM6DSO_SPI,
L3GD20_SPI,
+ BMI_088_SPI
} mpuSensor_e;
typedef enum {
diff --git a/src/main/drivers/accgyro/accgyro_spi_bmi088.c b/src/main/drivers/accgyro/accgyro_spi_bmi088.c
new file mode 100644
index 0000000000..d045f5f74d
--- /dev/null
+++ b/src/main/drivers/accgyro/accgyro_spi_bmi088.c
@@ -0,0 +1,424 @@
+/*
+ * This file is part of Rotorflight.
+ *
+ * Rotorflight 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.
+ *
+ * Rotorflight 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 this software. If not, see .
+ */
+
+#include
+#include
+#include
+
+#include "platform.h"
+
+#ifdef USE_ACCGYRO_SPI_BMI088
+
+#include "drivers/accgyro/accgyro.h"
+#include "drivers/bus_spi.h"
+#include "drivers/exti.h"
+#include "drivers/io.h"
+#include "drivers/io_impl.h"
+#include "drivers/nvic.h"
+#include "drivers/sensor.h"
+#include "drivers/system.h"
+#include "drivers/time.h"
+
+#include "sensors/gyro.h"
+
+#include "accgyro.h"
+#include "accgyro_spi_bmi088.h"
+
+#define BMI088_MAX_SPI_CLK_HZ 10000000
+#define GYRO_EXTI_DETECT_THRESHOLD 1000
+
+#define BMI088_REG_GYRO_CHIP_ID 0x00
+#define BMI088_GYRO_CHIP_ID 0x0F
+#define BMI088_REG_GYRO_RANGE 0x0F
+#define BMI088_REG_GYRO_BANDWIDTH 0x10
+#define BMI088_REG_GYRO_RATE_DATA 0x02
+#define BMI088_REG_GYRO_SOFTRESET 0x14
+#define BMI088_REG_GYRO_INT_CTRL 0x15
+#define BMI088_REG_GYRO_INT3_INT4_IO_CONF 0x16
+#define BMI088_REG_GYRO_INT3_INT4_IO_MAP 0x18
+#define BMI088_REG_GYRO_SELF_TEST 0x3C
+#define BMI088_EN_DRDY_INT 0x80
+
+#define BMI088_REG_ACC_CHIP_ID 0x00
+#define BMI088_ACC_CHIP_ID 0x1E
+#define BMI088_REG_ACC_CONF 0x40
+#define BMI088_REG_ACC_RANGE 0x41
+#define BMI088_REG_ACC_PWR_CONF 0x7C
+#define BMI088_REG_ACC_PWR_CTRL 0x7D
+#define BMI088_REG_ACC_SOFTRESET 0x7E
+#define BMI088_REG_ACC_DATA 0x12
+#define BMI088_TRIGGER_SOFTRESET 0xB6
+
+enum bmi088_accc_range{
+ BMI088_A_RANGE_3G = 0x00,
+ BMI088_A_RANGE_6G = 0x01,
+ BMI088_A_RANGE_12G = 0x02,
+ BMI088_A_RANGE_24G = 0x03,
+};
+enum bmi088_acc_pwr_save{
+ BMI088_A_ACTIVE = 0x00,
+ BMI088_A_SUSPEND = 0x03,
+};
+enum bmi088_acc_enable{
+ BMI088_A_OFF = 0x00,
+ BMI088_A_ON = 0x04,
+};
+enum bmi088_acc_bwp{
+ BMI088_A_BWP_OSR4 = 0x00,
+ BMI088_A_BWP_OSR2 = 0x01,
+ BMI088_A_BWP_NORMAL = 0x02,
+};
+enum bmi088_acc_odr{
+ BMI088_A_ODR_12_5 = 0x05,
+ BMI088_A_ODR_25 = 0x06,
+ BMI088_A_ODR_50 = 0x07,
+ BMI088_A_ODR_100 = 0x08,
+ BMI088_A_ODR_200 = 0x09,
+ BMI088_A_ODR_400 = 0x0A,
+ BMI088_A_ODR_800 = 0x0B,
+ BMI088_A_ODR_1600 = 0x0C,
+};
+enum bmi088_gyro_bandwidth{
+ BMI088_G_BANDWIDTH_532HZ = 0x00,
+ BMI088_G_BANDWIDTH_230HZ = 0x01,
+ BMI088_G_BANDWIDTH_116HZ = 0x02,
+ BMI088_G_BANDWIDTH_47HZ = 0x03,
+ BMI088_G_BANDWIDTH_23HZ = 0x04,
+ BMI088_G_BANDWIDTH_12HZ = 0x05,
+ BMI088_G_BANDWIDTH_64HZ = 0x06,
+ BMI088_G_BANDWIDTH_32HZ = 0x07,
+};
+enum bmi088_gyro_range {
+ BMI088_G_RANGE_125DPS = 0x04,
+ BMI088_G_RANGE_250DPS = 0x03,
+ BMI088_G_RANGE_500DPS = 0x02,
+ BMI088_G_RANGE_1000DPS = 0x01,
+ BMI088_G_RANGE_2000DPS = 0x00,
+};
+
+void bmi088ExtiHandler(extiCallbackRec_t *cb);
+void bmi088SpiGyroInit(gyroDev_t *gyro);
+bool bmi088GyroRead(gyroDev_t *gyro);
+bool bmi088SpiGyroDetect(gyroDev_t *gyro);
+bool bmi088AccRead(accDev_t *acc);
+uint8_t bmi088spiBusReadRegisterAcc(const extDevice_t *dev, const uint8_t reg);
+bool bmi088SpiAccDetect(accDev_t *acc);
+void bmi088SpiAccInit(accDev_t *acc);
+static volatile bool BMI088GyroDetected = false;
+static volatile bool BMI088AccDetected = false;
+static DMA_DATA uint8_t accBuf[32];
+
+void bmi088ExtiHandler(extiCallbackRec_t *cb)
+{
+ gyroDev_t *gyro = container_of(cb, gyroDev_t, exti);
+ gyro->dataReady = true;
+}
+
+void bmi088SpiGyroInit(gyroDev_t *gyro)
+{
+ extDevice_t *dev = &gyro->dev;
+ // softreset
+ spiWriteReg(dev, BMI088_REG_GYRO_SOFTRESET, BMI088_TRIGGER_SOFTRESET);
+ delay(30);
+
+ //config sensor
+
+ spiWriteReg(dev, BMI088_REG_GYRO_RANGE, BMI088_G_RANGE_2000DPS);
+ spiWriteReg(dev, BMI088_REG_GYRO_BANDWIDTH, BMI088_G_BANDWIDTH_230HZ);
+
+ // enable dataready interrupt
+ spiWriteReg(dev, BMI088_REG_GYRO_INT_CTRL, BMI088_EN_DRDY_INT);
+
+ // INT3: push-pull, active high
+ spiWriteReg(dev, BMI088_REG_GYRO_INT3_INT4_IO_CONF, 0x01);
+
+ // DRDY int is mapped to INT3 pin
+ spiWriteReg(dev, BMI088_REG_GYRO_INT3_INT4_IO_MAP, 0x01);
+
+ IO_t mpuIntIO = IOGetByTag(gyro->mpuIntExtiTag);
+
+ IOInit(mpuIntIO, OWNER_GYRO_EXTI, 0);
+ EXTIHandlerInit(&gyro->exti, bmi088ExtiHandler);
+ EXTIConfig(mpuIntIO, &gyro->exti, NVIC_PRIO_MPU_INT_EXTI, IOCFG_IN_FLOATING, BETAFLIGHT_EXTI_TRIGGER_RISING); // TODO - maybe pullup / pulldown ?
+ EXTIEnable(mpuIntIO);
+}
+
+extiCallbackRec_t bmi088IntCallbackRec;
+
+busStatus_e bmi088Intcallback(uint32_t arg)
+{
+ gyroDev_t *gyro = (gyroDev_t *)arg;
+ int32_t gyroDmaDuration = cmpTimeCycles(getCycleCounter(), gyro->gyroLastEXTI);
+
+ if (gyroDmaDuration > gyro->gyroDmaMaxDuration) {
+ gyro->gyroDmaMaxDuration = gyroDmaDuration;
+ }
+
+ gyro->dataReady = true;
+
+ return BUS_READY;
+}
+
+bool bmi088GyroRead(gyroDev_t *gyro)
+{
+ extDevice_t *dev = &gyro->dev;
+
+ switch (gyro->gyroModeSPI) {
+ case GYRO_EXTI_INIT:
+ {
+ // Initialise the tx buffer to all 0x00
+ memset(dev->txBuf, 0x00, 8);
+
+ // Check that minimum number of interrupts have been detected
+ // We need some offset from the gyro interrupts to ensure sampling after the interrupt
+ gyro->gyroDmaMaxDuration = 5;
+ // Using DMA for gyro access upsets the scheduler on the F4
+ if (gyro->detectedEXTI > GYRO_EXTI_DETECT_THRESHOLD) {
+ if (spiUseDMA(dev)) {
+ dev->callbackArg = (uint32_t)gyro;
+ dev->txBuf[1] = BMI088_REG_GYRO_RATE_DATA | 0x80;
+ gyro->segments[0].len = 8;
+ gyro->segments[0].callback = bmi088Intcallback;
+ gyro->segments[0].u.buffers.txData = dev->txBuf;
+ gyro->segments[0].u.buffers.rxData = dev->rxBuf;
+ gyro->segments[0].negateCS = true;
+ gyro->gyroModeSPI = GYRO_EXTI_INT_DMA;
+ } else {
+ // Interrupts are present, but no DMA
+ gyro->gyroModeSPI = GYRO_EXTI_INT;
+ }
+ } else {
+ gyro->gyroModeSPI = GYRO_EXTI_NO_INT;
+ }
+ break;
+ }
+
+ case GYRO_EXTI_INT:
+ case GYRO_EXTI_NO_INT:
+ {
+ dev->txBuf[0] = BMI088_REG_GYRO_RATE_DATA | 0x80;
+
+ busSegment_t segments[] = {
+ {.u.buffers = {NULL, NULL}, 7, true, NULL},
+ {.u.link = {NULL, NULL}, 0, true, NULL},
+ };
+ segments[0].u.buffers.txData = dev->txBuf;
+ segments[0].u.buffers.rxData = dev->rxBuf;
+
+ spiSequence(dev, &segments[0]);
+
+ // Wait for completion
+ spiWait(dev);
+
+ FALLTHROUGH;
+ }
+
+ case GYRO_EXTI_INT_DMA:
+ {
+ int16_t *gyroData = (int16_t *)&dev->rxBuf[1];//first byte is the register address
+ gyro->gyroADCRaw[X] = gyroData[0];
+ gyro->gyroADCRaw[Y] = gyroData[1];
+ gyro->gyroADCRaw[Z] = gyroData[2];
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return true;
+}
+
+uint8_t bmi088SpiDetect(const extDevice_t *dev)
+{
+ if (BMI088GyroDetected) {
+ return BMI_088_SPI;
+ }
+
+ spiSetClkDivisor(dev, spiCalculateDivider(BMI088_MAX_SPI_CLK_HZ));
+
+ //init ACC cs to avoid comminication conflicts
+ /*acc_cs_pin = IOGetByTag(IO_TAG(BMI088_CS_A_PIN));
+ IOInit(acc_cs_pin, OWNER_ACC_CS, 0);
+ IOConfigGPIO(acc_cs_pin, IOCFG_OUT_PP);
+ IOHi(acc_cs_pin);*/
+
+ if (spiReadReg(dev, BMI088_REG_GYRO_CHIP_ID | 0x80) != BMI088_GYRO_CHIP_ID) {
+ return MPU_NONE;
+ }
+
+ BMI088GyroDetected = true;
+
+ return BMI_088_SPI;
+}
+
+bool bmi088SpiGyroDetect(gyroDev_t *gyro)
+{
+ if(gyro->mpuDetectionResult.sensor != BMI_088_SPI){
+ return false;
+ }
+ uint8_t resultBITE = spiReadReg(&gyro->dev, BMI088_REG_GYRO_SELF_TEST| 0x80);
+
+ //trigger BITE
+ spiWriteReg(&gyro->dev, BMI088_REG_GYRO_SELF_TEST, 0x01);
+ uint8_t startBITETime = millis();
+ do{
+ resultBITE = spiReadReg(&gyro->dev, BMI088_REG_GYRO_SELF_TEST| 0x80);
+ }while(startBITETime - millis() < 50 && (resultBITE & 0x02) != 0x02);
+
+
+ if((resultBITE & 0x04) == 0x04){
+ //BITE failed
+ return false;
+ }
+
+
+ gyro->initFn = bmi088SpiGyroInit;
+ gyro->readFn = bmi088GyroRead;
+ gyro->scale = GYRO_SCALE_2000DPS;
+
+ return true;
+}
+
+
+bool bmi088AccRead(accDev_t *acc)
+{
+ extDevice_t *dev = &acc->dev;
+
+ switch (acc->gyro->gyroModeSPI) {
+ case GYRO_EXTI_INT:
+ case GYRO_EXTI_NO_INT:
+ {
+ memset(dev->txBuf, 0x00, 8);
+
+ dev->txBuf[0] = BMI088_REG_ACC_DATA | 0x80;
+
+ busSegment_t segments[] = {
+ {.u.buffers = {NULL, NULL}, 8, true, NULL},
+ {.u.link = {NULL, NULL}, 0, true, NULL},
+ };
+ segments[0].u.buffers.txData = dev->txBuf;
+ segments[0].u.buffers.rxData = dev->rxBuf;
+
+ spiSequence(dev, &segments[0]);
+
+ // Wait for completion
+ spiWait(dev);
+
+ // Fall through
+ FALLTHROUGH;
+ }
+
+ case GYRO_EXTI_INT_DMA:
+ {
+ int16_t *accData = (int16_t *)dev->rxBuf; //first byte = reg addr, second byte = dummy
+ acc->ADCRaw[X] = accData[1];
+ acc->ADCRaw[Y] = accData[2];
+ acc->ADCRaw[Z] = accData[3];
+ break;
+ }
+
+ case GYRO_EXTI_INIT:
+ default:
+ break;
+ }
+
+ return true;
+}
+
+uint8_t bmi088spiBusReadRegisterAcc(const extDevice_t *dev, const uint8_t reg)
+{
+ uint8_t data[2] = { 0 };
+
+ if (spiReadRegMskBufRB(dev, reg, data, 2)) {
+ return data[1];
+ } else {
+ return 0;
+ }
+}
+
+void bmi088SpiAccInit(accDev_t *acc)
+{
+ //softreset
+ spiWriteReg(&acc->dev, BMI088_REG_ACC_SOFTRESET, BMI088_TRIGGER_SOFTRESET);
+ delay(1);
+
+ // dummy read
+ bmi088spiBusReadRegisterAcc(&acc->dev, BMI088_REG_ACC_CHIP_ID);
+
+ // From datasheet page 12:
+ // Power up the sensor
+ // wait 1ms
+ // enter normal mode by writing '4' to ACC_PWR_CTRL
+ // wait for 50 ms
+ spiWriteReg(&acc->dev, BMI088_REG_ACC_PWR_CTRL, BMI088_A_ON);
+ delay(50);
+
+ for(uint8_t i = 0 ; i<5;i++){
+ if(bmi088spiBusReadRegisterAcc(&acc->dev, BMI088_REG_ACC_PWR_CTRL) == BMI088_A_ON){
+ break;
+ }
+ delay(5);
+ }
+
+ uint8_t range = bmi088spiBusReadRegisterAcc(&acc->dev, BMI088_REG_ACC_RANGE);
+ spiWriteReg(&acc->dev, BMI088_REG_ACC_RANGE, (range & 0xFC) | BMI088_A_RANGE_12G);
+
+ spiWriteReg(&acc->dev, BMI088_REG_ACC_CONF,
+ 0x80 | (BMI088_A_BWP_NORMAL<<4) | BMI088_A_ODR_800);
+
+ spiWriteReg(&acc->dev, BMI088_REG_ACC_PWR_CONF, BMI088_A_ACTIVE);
+ delay(10);
+
+ acc->acc_1G = 2731; // 32768 / 12G
+}
+
+bool bmi088SpiAccDetect(accDev_t *acc)
+{
+ if(acc->mpuDetectionResult.sensor != BMI_088_SPI){
+ return false;
+ }
+
+ //ACC part uses the same SPI bus as the gyro, so we can just use the gyro's spi instance
+ spiSetBusInstance(&acc->dev, SPI_DEV_TO_CFG(spiDeviceByInstance(acc->gyro->dev.bus->busType_u.spi.instance)));
+ acc->dev.busType_u.spi.csnPin = acc->gyro->csnAccPin; //get the CS pin from the gyro device config
+ acc->dev.txBuf = accBuf;
+ acc->dev.rxBuf = &accBuf[32 / 2];
+
+ spiSetClkDivisor(&acc->dev, spiCalculateDivider(BMI088_MAX_SPI_CLK_HZ));
+
+ // perform dummy-read to switch the accel to SPI-mode
+ bmi088spiBusReadRegisterAcc(&acc->dev, BMI088_REG_ACC_CHIP_ID);
+ delay(5);
+
+ if (bmi088spiBusReadRegisterAcc(&acc->dev, BMI088_REG_ACC_CHIP_ID) != BMI088_ACC_CHIP_ID) {
+ return false;
+ }
+
+ //TODO: check ACC_ERR_REG
+
+ BMI088AccDetected = true;
+
+ acc->initFn = bmi088SpiAccInit;
+ acc->readFn = bmi088AccRead;
+
+ busDeviceRegister(&acc->dev);
+
+ return true;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/main/drivers/accgyro/accgyro_spi_bmi088.h b/src/main/drivers/accgyro/accgyro_spi_bmi088.h
new file mode 100644
index 0000000000..9c5b102ecf
--- /dev/null
+++ b/src/main/drivers/accgyro/accgyro_spi_bmi088.h
@@ -0,0 +1,24 @@
+/*
+ * This file is part of Rotorflight.
+ *
+ * Rotorflight 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.
+ *
+ * Rotorflight 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 this software. If not, see .
+ */
+
+#pragma once
+
+#include "drivers/bus.h"
+
+uint8_t bmi088SpiDetect(const extDevice_t *dev);
+bool bmi088SpiGyroDetect(gyroDev_t *gyro);
+bool bmi088SpiAccDetect(accDev_t *acc);
\ No newline at end of file
diff --git a/src/main/drivers/accgyro/gyro_sync.c b/src/main/drivers/accgyro/gyro_sync.c
index 779c8cc092..3e5f471e98 100644
--- a/src/main/drivers/accgyro/gyro_sync.c
+++ b/src/main/drivers/accgyro/gyro_sync.c
@@ -69,6 +69,12 @@ void gyroSetSampleRate(gyroDev_t *gyro)
accSampleRateHz = 800;
break;
+ case BMI_088_SPI:
+ gyro->gyroRateKHz = GYRO_RATE_2000_Hz;
+ gyroSampleRateHz = 2000;
+ accSampleRateHz = 800;
+ break;
+
case BMI_270_SPI:
#ifdef USE_GYRO_DLPF_EXPERIMENTAL
if (gyro->hardware_lpf == GYRO_HARDWARE_LPF_EXPERIMENTAL) {
diff --git a/src/main/drivers/resource.c b/src/main/drivers/resource.c
index 91f1a296a2..5de43e6543 100644
--- a/src/main/drivers/resource.c
+++ b/src/main/drivers/resource.c
@@ -113,4 +113,5 @@ const char * const ownerNames[OWNER_TOTAL_COUNT] = {
"RX_SPI_EXPRESSLRS_RESET",
"RX_SPI_EXPRESSLRS_BUSY",
"FREQ",
+ "ACC_CS",
};
diff --git a/src/main/drivers/resource.h b/src/main/drivers/resource.h
index 5c7a4a08b5..dec510658b 100644
--- a/src/main/drivers/resource.h
+++ b/src/main/drivers/resource.h
@@ -111,6 +111,7 @@ typedef enum {
OWNER_RX_SPI_EXPRESSLRS_RESET,
OWNER_RX_SPI_EXPRESSLRS_BUSY,
OWNER_FREQ,
+ OWNER_ACC_CS,
OWNER_TOTAL_COUNT
} resourceOwner_e;
diff --git a/src/main/msp/msp.c b/src/main/msp/msp.c
index 5ff4896acd..09d4375784 100644
--- a/src/main/msp/msp.c
+++ b/src/main/msp/msp.c
@@ -1074,8 +1074,10 @@ static bool mspProcessOutCommand(int16_t cmdMSP, sbuf_t *dst)
#if defined(USE_ACC)
// Hack scale due to choice of units for sensor data in multiwii
- uint8_t scale;
- if (acc.dev.acc_1G > 512 * 4) {
+ float scale;
+ if (acc.dev.acc_1G == 2731){
+ scale = 16/3.0;
+ } else if (acc.dev.acc_1G > 512 * 4) {
scale = 8;
} else if (acc.dev.acc_1G > 512 * 2) {
scale = 4;
diff --git a/src/main/pg/accel.h b/src/main/pg/accel.h
index 015182a4c3..a01c7adc4f 100644
--- a/src/main/pg/accel.h
+++ b/src/main/pg/accel.h
@@ -47,6 +47,7 @@ typedef enum {
ACC_BMI160,
ACC_BMI270,
ACC_LSM6DSO,
+ ACC_BMI088,
ACC_FAKE
} accelerationSensor_e;
diff --git a/src/main/pg/gyrodev.c b/src/main/pg/gyrodev.c
index 87510d8d67..84a7894b73 100644
--- a/src/main/pg/gyrodev.c
+++ b/src/main/pg/gyrodev.c
@@ -47,11 +47,12 @@ static void gyroResetCommonDeviceConfig(gyroDeviceConfig_t *devconf, ioTag_t ext
#endif
#ifdef USE_SPI_GYRO
-static void gyroResetSpiDeviceConfig(gyroDeviceConfig_t *devconf, SPI_TypeDef *instance, ioTag_t csnTag, ioTag_t extiTag, uint8_t alignment, sensorAlignment_t customAlignment)
+static void gyroResetSpiDeviceConfig(gyroDeviceConfig_t *devconf, SPI_TypeDef *instance, ioTag_t csnTag, ioTag_t csnAccTag, ioTag_t extiTag, uint8_t alignment, sensorAlignment_t customAlignment)
{
devconf->busType = BUS_TYPE_SPI;
devconf->spiBus = SPI_DEV_TO_CFG(spiDeviceByInstance(instance));
devconf->csnTag = csnTag;
+ devconf->csnAccTag = csnAccTag;
gyroResetCommonDeviceConfig(devconf, extiTag, alignment, customAlignment);
}
#endif
@@ -80,7 +81,7 @@ void pgResetFn_gyroDeviceConfig(gyroDeviceConfig_t *devconf)
// All multi-gyro boards use SPI based gyros.
#ifdef USE_SPI_GYRO
- gyroResetSpiDeviceConfig(&devconf[0], GYRO_1_SPI_INSTANCE, IO_TAG(GYRO_1_CS_PIN), IO_TAG(GYRO_1_EXTI_PIN), GYRO_1_ALIGN, customAlignment1);
+ gyroResetSpiDeviceConfig(&devconf[0], GYRO_1_SPI_INSTANCE, IO_TAG(GYRO_1_CS_PIN), IO_TAG(GYRO_1_ACC_CS_PIN), IO_TAG(GYRO_1_EXTI_PIN), GYRO_1_ALIGN, customAlignment1);
#ifdef USE_MULTI_GYRO
devconf[1].index = 1;
sensorAlignment_t customAlignment2 = CUSTOM_ALIGN_CW0_DEG;
@@ -89,7 +90,7 @@ void pgResetFn_gyroDeviceConfig(gyroDeviceConfig_t *devconf)
#else
buildAlignmentFromStandardAlignment(&customAlignment2, GYRO_2_ALIGN);
#endif // GYRO_2_CUSTOM_ALIGN
- gyroResetSpiDeviceConfig(&devconf[1], GYRO_2_SPI_INSTANCE, IO_TAG(GYRO_2_CS_PIN), IO_TAG(GYRO_2_EXTI_PIN), GYRO_2_ALIGN, customAlignment2);
+ gyroResetSpiDeviceConfig(&devconf[1], GYRO_2_SPI_INSTANCE, IO_TAG(GYRO_2_CS_PIN), IO_TAG(GYRO_2_ACC_CS_PIN), IO_TAG(GYRO_2_EXTI_PIN), GYRO_2_ALIGN, customAlignment2);
#endif // USE_MULTI_GYRO
#endif // USE_SPI_GYRO
diff --git a/src/main/pg/gyrodev.h b/src/main/pg/gyrodev.h
index cba8dc192b..b6456b63cb 100644
--- a/src/main/pg/gyrodev.h
+++ b/src/main/pg/gyrodev.h
@@ -32,6 +32,7 @@ typedef struct gyroDeviceConfig_s {
uint8_t busType;
uint8_t spiBus;
ioTag_t csnTag;
+ ioTag_t csnAccTag;
uint8_t i2cBus;
uint8_t i2cAddress;
ioTag_t extiTag;
diff --git a/src/main/sensors/acceleration_init.c b/src/main/sensors/acceleration_init.c
index 2d2e4975f3..e61c8ba47e 100644
--- a/src/main/sensors/acceleration_init.c
+++ b/src/main/sensors/acceleration_init.c
@@ -44,6 +44,7 @@
#include "drivers/accgyro/accgyro_mpu6500.h"
#include "drivers/accgyro/accgyro_spi_bmi160.h"
#include "drivers/accgyro/accgyro_spi_bmi270.h"
+#include "drivers/accgyro/accgyro_spi_bmi088.h"
#include "drivers/accgyro/accgyro_spi_icm20649.h"
#include "drivers/accgyro/accgyro_spi_icm20689.h"
#include "drivers/accgyro/accgyro_spi_icm426xx.h"
@@ -274,6 +275,15 @@ bool accDetect(accDev_t *dev, accelerationSensor_e accHardwareToUse)
FALLTHROUGH;
#endif
+#ifdef USE_ACCGYRO_SPI_BMI088
+ case ACC_BMI088:
+ if (bmi088SpiAccDetect(dev)) {
+ accHardware = ACC_BMI088;
+ break;
+ }
+ FALLTHROUGH;
+#endif
+
#ifdef USE_ACCGYRO_LSM6DSO
case ACC_LSM6DSO:
if (lsm6dsoSpiAccDetect(dev)) {
diff --git a/src/main/sensors/gyro_init.c b/src/main/sensors/gyro_init.c
index 1d795eea42..3467e846d6 100644
--- a/src/main/sensors/gyro_init.c
+++ b/src/main/sensors/gyro_init.c
@@ -42,6 +42,7 @@
#include "drivers/accgyro/accgyro_mpu6500.h"
#include "drivers/accgyro/accgyro_spi_bmi160.h"
#include "drivers/accgyro/accgyro_spi_bmi270.h"
+#include "drivers/accgyro/accgyro_spi_bmi088.h"
#include "drivers/accgyro/accgyro_spi_icm20649.h"
#include "drivers/accgyro/accgyro_spi_icm20689.h"
#include "drivers/accgyro/accgyro_spi_icm20689.h"
@@ -216,6 +217,7 @@ void gyroInitSensor(gyroSensor_t *gyroSensor, const gyroDeviceConfig_t *config)
case GYRO_L3GD20:
case GYRO_BMI160:
case GYRO_BMI270:
+ case GYRO_BMI088:
case GYRO_MPU6000:
case GYRO_MPU6500:
case GYRO_MPU9250:
@@ -388,6 +390,15 @@ STATIC_UNIT_TESTED gyroHardware_e gyroDetect(gyroDev_t *dev)
FALLTHROUGH;
#endif
+#ifdef USE_ACCGYRO_SPI_BMI088
+ case GYRO_BMI088:
+ if (bmi088SpiGyroDetect(dev)) {
+ gyroHardware = GYRO_BMI088;
+ break;
+ }
+ FALLTHROUGH;
+#endif
+
#ifdef USE_ACCGYRO_LSM6DSO
case GYRO_LSM6DSO:
if (lsm6dsoSpiGyroDetect(dev)) {
@@ -422,7 +433,7 @@ static bool gyroDetectSensor(gyroSensor_t *gyroSensor, const gyroDeviceConfig_t
{
#if defined(USE_GYRO_MPU6050) || defined(USE_GYRO_MPU3050) || defined(USE_GYRO_MPU6500) || defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU6000) \
|| defined(USE_ACC_MPU6050) || defined(USE_GYRO_SPI_MPU9250) || defined(USE_GYRO_SPI_ICM20601) || defined(USE_GYRO_SPI_ICM20649) \
- || defined(USE_GYRO_SPI_ICM20689) || defined(USE_GYRO_L3GD20) || defined(USE_ACCGYRO_BMI160) || defined(USE_ACCGYRO_BMI270) || defined(USE_ACCGYRO_LSM6DSO) || defined(USE_GYRO_SPI_ICM42605) || defined(USE_GYRO_SPI_ICM42688P)
+ || defined(USE_GYRO_SPI_ICM20689) || defined(USE_GYRO_L3GD20) || defined(USE_ACCGYRO_BMI160) || defined(USE_ACCGYRO_BMI270) || defined(USE_ACCGYRO_SPI_BMI088) || defined(USE_ACCGYRO_LSM6DSO) || defined(USE_GYRO_SPI_ICM42605) || defined(USE_GYRO_SPI_ICM42688P)
bool gyroFound = mpuDetect(&gyroSensor->gyroDev, config);
@@ -447,7 +458,7 @@ static void gyroPreInitSensor(const gyroDeviceConfig_t *config)
{
#if defined(USE_GYRO_MPU6050) || defined(USE_GYRO_MPU3050) || defined(USE_GYRO_MPU6500) || defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU6000) \
|| defined(USE_ACC_MPU6050) || defined(USE_GYRO_SPI_MPU9250) || defined(USE_GYRO_SPI_ICM20601) || defined(USE_GYRO_SPI_ICM20649) \
- || defined(USE_GYRO_SPI_ICM20689) || defined(USE_ACCGYRO_BMI160) || defined(USE_ACCGYRO_BMI270) || defined(USE_ACCGRYO_LSM6DSO)
+ || defined(USE_GYRO_SPI_ICM20689) || defined(USE_ACCGYRO_BMI160) || defined(USE_ACCGYRO_BMI270) || defined(USE_ACCGYRO_SPI_BMI088) || defined(USE_ACCGRYO_LSM6DSO)
mpuPreInit(config);
#else
UNUSED(config);
diff --git a/src/main/target/STM32_UNIFIED/target.h b/src/main/target/STM32_UNIFIED/target.h
index 8e1d6a57f8..75e29d8e54 100644
--- a/src/main/target/STM32_UNIFIED/target.h
+++ b/src/main/target/STM32_UNIFIED/target.h
@@ -329,6 +329,7 @@
#define USE_ACCGYRO_LSM6DSO
#define USE_ACCGYRO_BMI160
#define USE_ACCGYRO_BMI270
+#define USE_ACCGYRO_SPI_BMI088
#define USE_GYRO_SPI_ICM42605
#define USE_GYRO_SPI_ICM42688P
#define USE_ACC_SPI_ICM42605
diff --git a/src/main/target/common_defaults_post.h b/src/main/target/common_defaults_post.h
index 870d9e4b01..f75eae376f 100644
--- a/src/main/target/common_defaults_post.h
+++ b/src/main/target/common_defaults_post.h
@@ -328,6 +328,10 @@
#define GYRO_1_CS_PIN NONE
#endif
+#if !defined(GYRO_1_ACC_CS_PIN)
+#define GYRO_1_ACC_CS_PIN NONE
+#endif
+
#if !defined(GYRO_1_EXTI_PIN)
#define GYRO_1_EXTI_PIN NONE
#endif
@@ -336,6 +340,7 @@
#if defined(USE_MULTI_GYRO) && !defined(GYRO_2_SPI_INSTANCE)
#define GYRO_2_SPI_INSTANCE NULL
#define GYRO_2_CS_PIN NONE
+#define GYRO_2_ACC_CS_PIN NONE
#define GYRO_2_EXTI_PIN NONE
#endif
diff --git a/src/main/target/common_post.h b/src/main/target/common_post.h
index 035b352107..a59a0f3042 100644
--- a/src/main/target/common_post.h
+++ b/src/main/target/common_post.h
@@ -248,7 +248,7 @@
#define USE_I2C_GYRO
#endif
-#if defined(USE_GYRO_SPI_ICM20689) || defined(USE_GYRO_SPI_MPU6000) || defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU9250) || defined(USE_GYRO_L3GD20) || defined(USE_GYRO_SPI_ICM42605) || defined(USE_GYRO_SPI_ICM42688P)
+#if defined(USE_GYRO_SPI_ICM20689) || defined(USE_GYRO_SPI_MPU6000) || defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU9250) || defined(USE_GYRO_L3GD20) || defined(USE_GYRO_SPI_ICM42605) || defined(USE_GYRO_SPI_ICM42688P) || defined(USE_ACCGYRO_SPI_BMI088)
#define USE_SPI_GYRO
#endif