Merge pull request #11297 from SteveCEvans/baro_state
[betaflight.git] / src / main / drivers / accgyro / accgyro_spi_bmi270.c
blob7d034fd4614127cf9410734254d1a1e230e50871
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #include "platform.h"
28 #ifdef USE_ACCGYRO_BMI270
30 #include "drivers/accgyro/accgyro.h"
31 #include "drivers/accgyro/accgyro_spi_bmi270.h"
32 #include "drivers/bus_spi.h"
33 #include "drivers/exti.h"
34 #include "drivers/io.h"
35 #include "drivers/io_impl.h"
36 #include "drivers/nvic.h"
37 #include "drivers/sensor.h"
38 #include "drivers/system.h"
39 #include "drivers/time.h"
41 // 10 MHz max SPI frequency
42 #define BMI270_MAX_SPI_CLK_HZ 10000000
44 #define BMI270_FIFO_FRAME_SIZE 6
46 #define BMI270_CONFIG_SIZE 328
48 // Declaration for the device config (microcode) that must be uploaded to the sensor
49 extern const uint8_t bmi270_maximum_fifo_config_file[BMI270_CONFIG_SIZE];
51 #define BMI270_CHIP_ID 0x24
53 // BMI270 registers (not the complete list)
54 typedef enum {
55 BMI270_REG_CHIP_ID = 0x00,
56 BMI270_REG_ERR_REG = 0x02,
57 BMI270_REG_STATUS = 0x03,
58 BMI270_REG_ACC_DATA_X_LSB = 0x0C,
59 BMI270_REG_GYR_DATA_X_LSB = 0x12,
60 BMI270_REG_SENSORTIME_0 = 0x18,
61 BMI270_REG_SENSORTIME_1 = 0x19,
62 BMI270_REG_SENSORTIME_2 = 0x1A,
63 BMI270_REG_EVENT = 0x1B,
64 BMI270_REG_INT_STATUS_0 = 0x1C,
65 BMI270_REG_INT_STATUS_1 = 0x1D,
66 BMI270_REG_INTERNAL_STATUS = 0x21,
67 BMI270_REG_TEMPERATURE_LSB = 0x22,
68 BMI270_REG_TEMPERATURE_MSB = 0x23,
69 BMI270_REG_FIFO_LENGTH_LSB = 0x24,
70 BMI270_REG_FIFO_LENGTH_MSB = 0x25,
71 BMI270_REG_FIFO_DATA = 0x26,
72 BMI270_REG_ACC_CONF = 0x40,
73 BMI270_REG_ACC_RANGE = 0x41,
74 BMI270_REG_GYRO_CONF = 0x42,
75 BMI270_REG_GYRO_RANGE = 0x43,
76 BMI270_REG_AUX_CONF = 0x44,
77 BMI270_REG_FIFO_DOWNS = 0x45,
78 BMI270_REG_FIFO_WTM_0 = 0x46,
79 BMI270_REG_FIFO_WTM_1 = 0x47,
80 BMI270_REG_FIFO_CONFIG_0 = 0x48,
81 BMI270_REG_FIFO_CONFIG_1 = 0x49,
82 BMI270_REG_SATURATION = 0x4A,
83 BMI270_REG_INT1_IO_CTRL = 0x53,
84 BMI270_REG_INT2_IO_CTRL = 0x54,
85 BMI270_REG_INT_LATCH = 0x55,
86 BMI270_REG_INT1_MAP_FEAT = 0x56,
87 BMI270_REG_INT2_MAP_FEAT = 0x57,
88 BMI270_REG_INT_MAP_DATA = 0x58,
89 BMI270_REG_INIT_CTRL = 0x59,
90 BMI270_REG_INIT_DATA = 0x5E,
91 BMI270_REG_ACC_SELF_TEST = 0x6D,
92 BMI270_REG_GYR_SELF_TEST_AXES = 0x6E,
93 BMI270_REG_PWR_CONF = 0x7C,
94 BMI270_REG_PWR_CTRL = 0x7D,
95 BMI270_REG_CMD = 0x7E,
96 } bmi270Register_e;
98 // BMI270 register configuration values
99 typedef enum {
100 BMI270_VAL_CMD_SOFTRESET = 0xB6,
101 BMI270_VAL_CMD_FIFOFLUSH = 0xB0,
102 BMI270_VAL_PWR_CTRL = 0x0E, // enable gyro, acc and temp sensors
103 BMI270_VAL_PWR_CONF = 0x02, // disable advanced power save, enable FIFO self-wake
104 BMI270_VAL_ACC_CONF_ODR800 = 0x0B, // set acc sample rate to 800hz
105 BMI270_VAL_ACC_CONF_ODR1600 = 0x0C, // set acc sample rate to 1600hz
106 BMI270_VAL_ACC_CONF_BWP = 0x02, // set acc filter in normal mode
107 BMI270_VAL_ACC_CONF_HP = 0x01, // set acc in high performance mode
108 BMI270_VAL_ACC_RANGE_8G = 0x02, // set acc to 8G full scale
109 BMI270_VAL_ACC_RANGE_16G = 0x03, // set acc to 16G full scale
110 BMI270_VAL_GYRO_CONF_ODR3200 = 0x0D, // set gyro sample rate to 3200hz
111 BMI270_VAL_GYRO_CONF_BWP = 0x02, // set gyro filter in normal mode
112 BMI270_VAL_GYRO_CONF_NOISE_PERF = 0x01, // set gyro in high performance noise mode
113 BMI270_VAL_GYRO_CONF_FILTER_PERF = 0x01, // set gyro in high performance filter mode
115 BMI270_VAL_GYRO_RANGE_2000DPS = 0x08, // set gyro to 2000dps full scale
116 // for some reason you have to enable the ois_range bit (bit 3) for 2000dps as well
117 // or else the gyro scale will be 250dps when in prefiltered FIFO mode (not documented in datasheet!)
119 BMI270_VAL_INT_MAP_DATA_DRDY_INT1 = 0x04,// enable the data ready interrupt pin 1
120 BMI270_VAL_INT_MAP_FIFO_WM_INT1 = 0x02, // enable the FIFO watermark interrupt pin 1
121 BMI270_VAL_INT1_IO_CTRL_PINMODE = 0x0A, // active high, push-pull, output enabled, input disabled
122 BMI270_VAL_FIFO_CONFIG_0 = 0x00, // don't stop when full, disable sensortime frame
123 BMI270_VAL_FIFO_CONFIG_1 = 0x80, // only gyro data in FIFO, use headerless mode
124 BMI270_VAL_FIFO_DOWNS = 0x00, // select unfiltered gyro data with no downsampling (6.4KHz samples)
125 BMI270_VAL_FIFO_WTM_0 = 0x06, // set the FIFO watermark level to 1 gyro sample (6 bytes)
126 BMI270_VAL_FIFO_WTM_1 = 0x00, // FIFO watermark MSB
127 } bmi270ConfigValues_e;
129 // Need to see at least this many interrupts during initialisation to confirm EXTI connectivity
130 #define GYRO_EXTI_DETECT_THRESHOLD 1000
132 // BMI270 register reads are 16bits with the first byte a "dummy" value 0
133 // that must be ignored. The result is in the second byte.
134 static uint8_t bmi270RegisterRead(const extDevice_t *dev, bmi270Register_e registerId)
136 uint8_t data[2] = { 0, 0 };
138 if (spiReadRegMskBufRB(dev, registerId, data, 2)) {
139 return data[1];
140 } else {
141 return 0;
145 static void bmi270RegisterWrite(const extDevice_t *dev, bmi270Register_e registerId, uint8_t value, unsigned delayMs)
147 spiWriteReg(dev, registerId, value);
148 if (delayMs) {
149 delay(delayMs);
153 // Toggle the CS to switch the device into SPI mode.
154 // Device switches initializes as I2C and switches to SPI on a low to high CS transition
155 static void bmi270EnableSPI(const extDevice_t *dev)
157 IOLo(dev->busType_u.spi.csnPin);
158 delay(1);
159 IOHi(dev->busType_u.spi.csnPin);
160 delay(10);
163 uint8_t bmi270Detect(const extDevice_t *dev)
165 spiSetClkDivisor(dev, spiCalculateDivider(BMI270_MAX_SPI_CLK_HZ));
166 bmi270EnableSPI(dev);
168 if (bmi270RegisterRead(dev, BMI270_REG_CHIP_ID) == BMI270_CHIP_ID) {
169 return BMI_270_SPI;
172 return MPU_NONE;
175 static void bmi270UploadConfig(const extDevice_t *dev)
177 bmi270RegisterWrite(dev, BMI270_REG_PWR_CONF, 0, 1);
178 bmi270RegisterWrite(dev, BMI270_REG_INIT_CTRL, 0, 1);
180 // Transfer the config file
181 spiWriteRegBuf(dev, BMI270_REG_INIT_DATA, (uint8_t *)bmi270_maximum_fifo_config_file, sizeof(bmi270_maximum_fifo_config_file));
183 delay(10);
184 bmi270RegisterWrite(dev, BMI270_REG_INIT_CTRL, 1, 1);
187 static void bmi270Config(gyroDev_t *gyro)
189 extDevice_t *dev = &gyro->dev;
191 // If running in hardware_lpf experimental mode then switch to FIFO-based,
192 // 6.4KHz sampling, unfiltered data vs. the default 3.2KHz with hardware filtering
193 #ifdef USE_GYRO_DLPF_EXPERIMENTAL
194 const bool fifoMode = (gyro->hardware_lpf == GYRO_HARDWARE_LPF_EXPERIMENTAL);
195 #else
196 const bool fifoMode = false;
197 #endif
199 // Perform a soft reset to set all configuration to default
200 // Delay 100ms before continuing configuration
201 bmi270RegisterWrite(dev, BMI270_REG_CMD, BMI270_VAL_CMD_SOFTRESET, 100);
203 // Toggle the chip into SPI mode
204 bmi270EnableSPI(dev);
206 bmi270UploadConfig(dev);
208 // Configure the FIFO
209 if (fifoMode) {
210 bmi270RegisterWrite(dev, BMI270_REG_FIFO_CONFIG_0, BMI270_VAL_FIFO_CONFIG_0, 1);
211 bmi270RegisterWrite(dev, BMI270_REG_FIFO_CONFIG_1, BMI270_VAL_FIFO_CONFIG_1, 1);
212 bmi270RegisterWrite(dev, BMI270_REG_FIFO_DOWNS, BMI270_VAL_FIFO_DOWNS, 1);
213 bmi270RegisterWrite(dev, BMI270_REG_FIFO_WTM_0, BMI270_VAL_FIFO_WTM_0, 1);
214 bmi270RegisterWrite(dev, BMI270_REG_FIFO_WTM_1, BMI270_VAL_FIFO_WTM_1, 1);
217 // Configure the accelerometer
218 bmi270RegisterWrite(dev, BMI270_REG_ACC_CONF, (BMI270_VAL_ACC_CONF_HP << 7) | (BMI270_VAL_ACC_CONF_BWP << 4) | BMI270_VAL_ACC_CONF_ODR800, 1);
220 // Configure the accelerometer full-scale range
221 bmi270RegisterWrite(dev, BMI270_REG_ACC_RANGE, BMI270_VAL_ACC_RANGE_16G, 1);
223 // Configure the gyro
224 bmi270RegisterWrite(dev, BMI270_REG_GYRO_CONF, (BMI270_VAL_GYRO_CONF_FILTER_PERF << 7) | (BMI270_VAL_GYRO_CONF_NOISE_PERF << 6) | (BMI270_VAL_GYRO_CONF_BWP << 4) | BMI270_VAL_GYRO_CONF_ODR3200, 1);
226 // Configure the gyro full-range scale
227 bmi270RegisterWrite(dev, BMI270_REG_GYRO_RANGE, BMI270_VAL_GYRO_RANGE_2000DPS, 1);
229 // Configure the gyro data ready interrupt
230 if (fifoMode) {
231 // Interrupt driven by FIFO watermark level
232 bmi270RegisterWrite(dev, BMI270_REG_INT_MAP_DATA, BMI270_VAL_INT_MAP_FIFO_WM_INT1, 1);
233 } else {
234 // Interrupt driven by data ready
235 bmi270RegisterWrite(dev, BMI270_REG_INT_MAP_DATA, BMI270_VAL_INT_MAP_DATA_DRDY_INT1, 1);
238 // Configure the behavior of the INT1 pin
239 bmi270RegisterWrite(dev, BMI270_REG_INT1_IO_CTRL, BMI270_VAL_INT1_IO_CTRL_PINMODE, 1);
241 // Configure the device for performance mode
242 bmi270RegisterWrite(dev, BMI270_REG_PWR_CONF, BMI270_VAL_PWR_CONF, 1);
244 // Enable the gyro, accelerometer and temperature sensor - disable aux interface
245 bmi270RegisterWrite(dev, BMI270_REG_PWR_CTRL, BMI270_VAL_PWR_CTRL, 1);
247 // Flush the FIFO
248 if (fifoMode) {
249 bmi270RegisterWrite(dev, BMI270_REG_CMD, BMI270_VAL_CMD_FIFOFLUSH, 1);
253 extiCallbackRec_t bmi270IntCallbackRec;
256 * Gyro interrupt service routine
258 #ifdef USE_GYRO_EXTI
259 // Called in ISR context
260 // Gyro read has just completed
261 busStatus_e bmi270Intcallback(uint32_t arg)
263 gyroDev_t *gyro = (gyroDev_t *)arg;
264 int32_t gyroDmaDuration = cmpTimeCycles(getCycleCounter(), gyro->gyroLastEXTI);
266 if (gyroDmaDuration > gyro->gyroDmaMaxDuration) {
267 gyro->gyroDmaMaxDuration = gyroDmaDuration;
270 gyro->dataReady = true;
272 return BUS_READY;
275 void bmi270ExtiHandler(extiCallbackRec_t *cb)
277 gyroDev_t *gyro = container_of(cb, gyroDev_t, exti);
278 // Ideally we'd use a time to capture such information, but unfortunately the port used for EXTI interrupt does
279 // not have an associated timer
280 uint32_t nowCycles = getCycleCounter();
281 gyro->gyroSyncEXTI = gyro->gyroLastEXTI + gyro->gyroDmaMaxDuration;
282 gyro->gyroLastEXTI = nowCycles;
284 if (gyro->gyroModeSPI == GYRO_EXTI_INT_DMA) {
285 spiSequence(&gyro->dev, gyro->segments);
288 gyro->detectedEXTI++;
292 static void bmi270IntExtiInit(gyroDev_t *gyro)
294 if (gyro->mpuIntExtiTag == IO_TAG_NONE) {
295 return;
298 IO_t mpuIntIO = IOGetByTag(gyro->mpuIntExtiTag);
300 IOInit(mpuIntIO, OWNER_GYRO_EXTI, 0);
301 EXTIHandlerInit(&gyro->exti, bmi270ExtiHandler);
302 EXTIConfig(mpuIntIO, &gyro->exti, NVIC_PRIO_MPU_INT_EXTI, IOCFG_IN_FLOATING, BETAFLIGHT_EXTI_TRIGGER_RISING);
303 EXTIEnable(mpuIntIO, true);
305 #else
306 void bmi270ExtiHandler(extiCallbackRec_t *cb)
308 gyroDev_t *gyro = container_of(cb, gyroDev_t, exti);
309 gyro->dataReady = true;
311 #endif
313 static bool bmi270AccRead(accDev_t *acc)
315 switch (acc->gyro->gyroModeSPI) {
316 case GYRO_EXTI_INT:
317 case GYRO_EXTI_NO_INT:
319 acc->gyro->dev.txBuf[0] = BMI270_REG_ACC_DATA_X_LSB | 0x80;
321 busSegment_t segments[] = {
322 {.u.buffers = {NULL, NULL}, 8, true, NULL},
323 {.u.buffers = {NULL, NULL}, 0, true, NULL},
325 segments[0].u.buffers.txData = acc->gyro->dev.txBuf;
326 segments[0].u.buffers.rxData = acc->gyro->dev.rxBuf;
328 spiSequence(&acc->gyro->dev, &segments[0]);
330 // Wait for completion
331 spiWait(&acc->gyro->dev);
333 // Fall through
334 FALLTHROUGH;
337 case GYRO_EXTI_INT_DMA:
339 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
340 // up an old value.
342 // This data was read from the gyro, which is the same SPI device as the acc
343 uint16_t *accData = (uint16_t *)acc->gyro->dev.rxBuf;
344 acc->ADCRaw[X] = accData[1];
345 acc->ADCRaw[Y] = accData[2];
346 acc->ADCRaw[Z] = accData[3];
347 break;
350 case GYRO_EXTI_INIT:
351 default:
352 break;
355 return true;
358 static bool bmi270GyroReadRegister(gyroDev_t *gyro)
360 uint16_t *gyroData = (uint16_t *)gyro->dev.rxBuf;
361 switch (gyro->gyroModeSPI) {
362 case GYRO_EXTI_INIT:
364 // Initialise the tx buffer to all 0x00
365 memset(gyro->dev.txBuf, 0x00, 14);
366 #ifdef USE_GYRO_EXTI
367 // Check that minimum number of interrupts have been detected
369 // We need some offset from the gyro interrupts to ensure sampling after the interrupt
370 gyro->gyroDmaMaxDuration = 5;
371 // Using DMA for gyro access upsets the scheduler on the F4
372 if (gyro->detectedEXTI > GYRO_EXTI_DETECT_THRESHOLD) {
373 if (spiUseDMA(&gyro->dev)) {
374 gyro->dev.callbackArg = (uint32_t)gyro;
375 gyro->dev.txBuf[0] = BMI270_REG_ACC_DATA_X_LSB | 0x80;
376 gyro->segments[0].len = 14;
377 gyro->segments[0].callback = bmi270Intcallback;
378 gyro->segments[0].u.buffers.txData = gyro->dev.txBuf;
379 gyro->segments[0].u.buffers.rxData = gyro->dev.rxBuf;
380 gyro->segments[0].negateCS = true;
381 gyro->gyroModeSPI = GYRO_EXTI_INT_DMA;
382 } else {
383 // Interrupts are present, but no DMA
384 gyro->gyroModeSPI = GYRO_EXTI_INT;
386 } else
387 #endif
389 gyro->gyroModeSPI = GYRO_EXTI_NO_INT;
391 break;
394 case GYRO_EXTI_INT:
395 case GYRO_EXTI_NO_INT:
397 gyro->dev.txBuf[0] = BMI270_REG_GYR_DATA_X_LSB | 0x80;
399 busSegment_t segments[] = {
400 {.u.buffers = {NULL, NULL}, 8, true, NULL},
401 {.u.buffers = {NULL, NULL}, 0, true, NULL},
403 segments[0].u.buffers.txData = gyro->dev.txBuf;
404 segments[0].u.buffers.rxData = gyro->dev.rxBuf;
406 spiSequence(&gyro->dev, &segments[0]);
408 // Wait for completion
409 spiWait(&gyro->dev);
411 gyro->gyroADCRaw[X] = gyroData[1];
412 gyro->gyroADCRaw[Y] = gyroData[2];
413 gyro->gyroADCRaw[Z] = gyroData[3];
415 break;
418 case GYRO_EXTI_INT_DMA:
420 // If read was triggered in interrupt don't bother waiting. The worst that could happen is that we pick
421 // up an old value.
422 gyro->gyroADCRaw[X] = gyroData[4];
423 gyro->gyroADCRaw[Y] = gyroData[5];
424 gyro->gyroADCRaw[Z] = gyroData[6];
425 break;
428 default:
429 break;
432 return true;
435 #ifdef USE_GYRO_DLPF_EXPERIMENTAL
436 static bool bmi270GyroReadFifo(gyroDev_t *gyro)
438 enum {
439 IDX_REG = 0,
440 IDX_SKIP,
441 IDX_FIFO_LENGTH_L,
442 IDX_FIFO_LENGTH_H,
443 IDX_GYRO_XOUT_L,
444 IDX_GYRO_XOUT_H,
445 IDX_GYRO_YOUT_L,
446 IDX_GYRO_YOUT_H,
447 IDX_GYRO_ZOUT_L,
448 IDX_GYRO_ZOUT_H,
449 BUFFER_SIZE,
452 bool dataRead = false;
453 STATIC_DMA_DATA_AUTO uint8_t bmi270_tx_buf[BUFFER_SIZE] = {BMI270_REG_FIFO_LENGTH_LSB | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0};
454 STATIC_DMA_DATA_AUTO uint8_t bmi270_rx_buf[BUFFER_SIZE];
456 // Burst read the FIFO length followed by the next 6 bytes containing the gyro axis data for
457 // the first sample in the queue. It's possible for the FIFO to be empty so we need to check the
458 // length before using the sample.
459 spiReadWriteBuf(&gyro->dev, (uint8_t *)bmi270_tx_buf, bmi270_rx_buf, BUFFER_SIZE); // receive response
461 int fifoLength = (uint16_t)((bmi270_rx_buf[IDX_FIFO_LENGTH_H] << 8) | bmi270_rx_buf[IDX_FIFO_LENGTH_L]);
463 if (fifoLength >= BMI270_FIFO_FRAME_SIZE) {
465 const int16_t gyroX = (int16_t)((bmi270_rx_buf[IDX_GYRO_XOUT_H] << 8) | bmi270_rx_buf[IDX_GYRO_XOUT_L]);
466 const int16_t gyroY = (int16_t)((bmi270_rx_buf[IDX_GYRO_YOUT_H] << 8) | bmi270_rx_buf[IDX_GYRO_YOUT_L]);
467 const int16_t gyroZ = (int16_t)((bmi270_rx_buf[IDX_GYRO_ZOUT_H] << 8) | bmi270_rx_buf[IDX_GYRO_ZOUT_L]);
469 // If the FIFO data is invalid then the returned values will be 0x8000 (-32768) (pg. 43 of datasheet).
470 // This shouldn't happen since we're only using the data if the FIFO length indicates
471 // that data is available, but this safeguard is needed to prevent bad things in
472 // case it does happen.
473 if ((gyroX != INT16_MIN) || (gyroY != INT16_MIN) || (gyroZ != INT16_MIN)) {
474 gyro->gyroADCRaw[X] = gyroX;
475 gyro->gyroADCRaw[Y] = gyroY;
476 gyro->gyroADCRaw[Z] = gyroZ;
477 dataRead = true;
479 fifoLength -= BMI270_FIFO_FRAME_SIZE;
482 // If there are additional samples in the FIFO then we don't use those for now and simply
483 // flush the FIFO. Under normal circumstances we only expect one sample in the FIFO since
484 // the gyro loop is running at the native sample rate of 6.4KHz.
485 // However the way the FIFO works in the sensor is that if a frame is partially read then
486 // it remains in the queue instead of bein removed. So if we ever got into a state where there
487 // was a partial frame or other unexpected data in the FIFO is may never get cleared and we
488 // would end up in a lock state of always re-reading the same partial or invalid sample.
489 if (fifoLength > 0) {
490 // Partial or additional frames left - flush the FIFO
491 bmi270RegisterWrite(&gyro->dev, BMI270_REG_CMD, BMI270_VAL_CMD_FIFOFLUSH, 0);
494 return dataRead;
496 #endif
498 static bool bmi270GyroRead(gyroDev_t *gyro)
500 #ifdef USE_GYRO_DLPF_EXPERIMENTAL
501 if (gyro->hardware_lpf == GYRO_HARDWARE_LPF_EXPERIMENTAL) {
502 // running in 6.4KHz FIFO mode
503 return bmi270GyroReadFifo(gyro);
504 } else
505 #endif
507 // running in 3.2KHz register mode
508 return bmi270GyroReadRegister(gyro);
512 static void bmi270SpiGyroInit(gyroDev_t *gyro)
514 bmi270Config(gyro);
516 #if defined(USE_GYRO_EXTI)
517 bmi270IntExtiInit(gyro);
518 #endif
521 static void bmi270SpiAccInit(accDev_t *acc)
523 // sensor is configured during gyro init
524 acc->acc_1G = 512 * 4; // 16G sensor scale
527 bool bmi270SpiAccDetect(accDev_t *acc)
529 if (acc->mpuDetectionResult.sensor != BMI_270_SPI) {
530 return false;
533 acc->initFn = bmi270SpiAccInit;
534 acc->readFn = bmi270AccRead;
536 return true;
540 bool bmi270SpiGyroDetect(gyroDev_t *gyro)
542 if (gyro->mpuDetectionResult.sensor != BMI_270_SPI) {
543 return false;
546 gyro->initFn = bmi270SpiGyroInit;
547 gyro->readFn = bmi270GyroRead;
548 gyro->scale = GYRO_SCALE_2000DPS;
550 return true;
553 // Used to query the status register to determine what event caused the EXTI to fire.
554 // When in 3.2KHz mode the interrupt is mapped to the data ready state. However the data ready
555 // trigger will fire for both gyro and accelerometer. So it's necessary to check this register
556 // to determine which event caused the interrupt.
557 // When in 6.4KHz mode the interrupt is configured to be the FIFO watermark size of 6 bytes.
558 // Since in this mode we only put gyro data in the FIFO it's sufficient to check for the FIFO
559 // watermark reason as an idication of gyro data ready.
560 uint8_t bmi270InterruptStatus(gyroDev_t *gyro)
562 return bmi270RegisterRead(&gyro->dev, BMI270_REG_INT_STATUS_1);
564 #endif // USE_ACCGYRO_BMI270