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)
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/>.
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)
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,
98 // BMI270 register configuration values
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)) {
145 static void bmi270RegisterWrite(const extDevice_t
*dev
, bmi270Register_e registerId
, uint8_t value
, unsigned delayMs
)
147 spiWriteReg(dev
, registerId
, value
);
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
);
159 IOHi(dev
->busType_u
.spi
.csnPin
);
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
) {
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
));
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
);
196 const bool fifoMode
= false;
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
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
231 // Interrupt driven by FIFO watermark level
232 bmi270RegisterWrite(dev
, BMI270_REG_INT_MAP_DATA
, BMI270_VAL_INT_MAP_FIFO_WM_INT1
, 1);
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);
249 bmi270RegisterWrite(dev
, BMI270_REG_CMD
, BMI270_VAL_CMD_FIFOFLUSH
, 1);
253 extiCallbackRec_t bmi270IntCallbackRec
;
256 * Gyro interrupt service routine
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;
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
) {
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);
306 void bmi270ExtiHandler(extiCallbackRec_t
*cb
)
308 gyroDev_t
*gyro
= container_of(cb
, gyroDev_t
, exti
);
309 gyro
->dataReady
= true;
313 static bool bmi270AccRead(accDev_t
*acc
)
315 switch (acc
->gyro
->gyroModeSPI
) {
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
);
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
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];
358 static bool bmi270GyroReadRegister(gyroDev_t
*gyro
)
360 uint16_t *gyroData
= (uint16_t *)gyro
->dev
.rxBuf
;
361 switch (gyro
->gyroModeSPI
) {
364 // Initialise the tx buffer to all 0x00
365 memset(gyro
->dev
.txBuf
, 0x00, 14);
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
;
383 // Interrupts are present, but no DMA
384 gyro
->gyroModeSPI
= GYRO_EXTI_INT
;
389 gyro
->gyroModeSPI
= GYRO_EXTI_NO_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
411 gyro
->gyroADCRaw
[X
] = gyroData
[1];
412 gyro
->gyroADCRaw
[Y
] = gyroData
[2];
413 gyro
->gyroADCRaw
[Z
] = gyroData
[3];
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
422 gyro
->gyroADCRaw
[X
] = gyroData
[4];
423 gyro
->gyroADCRaw
[Y
] = gyroData
[5];
424 gyro
->gyroADCRaw
[Z
] = gyroData
[6];
435 #ifdef USE_GYRO_DLPF_EXPERIMENTAL
436 static bool bmi270GyroReadFifo(gyroDev_t
*gyro
)
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
;
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);
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
);
507 // running in 3.2KHz register mode
508 return bmi270GyroReadRegister(gyro
);
512 static void bmi270SpiGyroInit(gyroDev_t
*gyro
)
516 #if defined(USE_GYRO_EXTI)
517 bmi270IntExtiInit(gyro
);
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
) {
533 acc
->initFn
= bmi270SpiAccInit
;
534 acc
->readFn
= bmi270AccRead
;
540 bool bmi270SpiGyroDetect(gyroDev_t
*gyro
)
542 if (gyro
->mpuDetectionResult
.sensor
!= BMI_270_SPI
) {
546 gyro
->initFn
= bmi270SpiGyroInit
;
547 gyro
->readFn
= bmi270GyroRead
;
548 gyro
->scale
= GYRO_SCALE_2000DPS
;
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