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