Skip to content

Commit b2f5dd9

Browse files
BST-Github-Adminkegov
authored andcommitted
Updated the configuration file
Updated the code formatting Added APIs to utilize the accelerometer's FIFO
2 parents 89ed48a + 070cf16 commit b2f5dd9

2 files changed

Lines changed: 131 additions & 156 deletions

File tree

DataSync.md

Lines changed: 109 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,70 @@
1-
#### Configuring BMI085 for data synchronization
1+
# BMI085 data synchronization
2+
3+
## Introduction
4+
BMI085 is a system-in-package inertial measurement unit which offers accurate acceleration and angular rate measurements. Due to system-in-package approach (two sensors in single package), the gyroscope and acceleration data is acquired in a non-synchronized manner. However, the synchronization between accelerometer and gyroscope can be easily achieved. This document describes how synchronization between accelerometer and gyroscope can be achieved in a typical application such as augmented or virtual reality.
5+
6+
To achieve data synchronization on BMI085, the data ready interrupt signal from the gyroscope of the BMI085 needs to be connected to one of the interrupt pins of the BMI085 accelerometer (which can be configured as input pins). The internal signal processing unit of the accelerometer uses the data ready signal from the gyroscope to synchronize and interpolate the data of the accelerometer, considering the group delay of the sensors. The accelerometer part can then notify the host of available data. With this technique, it is possible to achieve synchronized data and provide accelerometer data at an ODR of 2 kHz.
7+
8+
_Note: data synchronization is designed for applications requiring high bandwidth, for which BMI085 is intended, but it works also with BMI088. However, for some applications it is desirable to have a very low bandwidth, and partly having different bandwidth settings for accelerometer and gyroscope. Here the synchronization feature does not make sense._
9+
10+
## Concept
11+
Synchronized data means that the acquisition of the gyroscope and accelerometer data is happening at the same time and the signals have same propagation time. The time between motion to register read-out depends on the physical propagation time mainly caused by signal filtering path. The synchronization between accelerometer and gyroscope data to a common point of time and a common group delay can be realized with the approach described in the following sections.
12+
13+
The hardware interrupts pins (INT1 / INT3) of the BMI085 are used for data synchronization purposes and must be connected. The interrupt pin INT2 can be used for data ready notification to the host by BMI085.
14+
15+
## Technical realization
16+
The data synchronization feature requires physical interrupt pin’s connection of the sensors on the pcb and a special configuration of the BMI085. Requirements and the steps are described below.
17+
18+
### Connection diagram
19+
20+
```
21+
MCU BMI085
22+
+-----------+ +---------------+
23+
| | 8 | | 16
24+
| SCK +------------>| SCK INT1 |<-----+
25+
| | 9 | | 12 |
26+
| MOSI +------------>| SDO INT3 |>-----+
27+
| | 15 | |
28+
| MISO +<------+-----| SDO1 |
29+
| | | 10 | |
30+
| | +-----| SDO2 |
31+
| | 14 | |
32+
| ACC_CSB +------------>| CSB1 |
33+
| | 5 | |
34+
| GYRO_CSB +------------>| CSB2 |
35+
| | 1 | |
36+
| DATA_RDY +<------------| INT2 PS +------+
37+
| | | | |
38+
+-----------+ +---------------+ |
39+
|
40+
---
41+
```
42+
43+
For latency-critical multisensory applications, it is recommended to use SPI interface for fastest sensor data read (recommended SPI clock speed is >2MHz).
44+
45+
### Configuring BMI085 for data synchronization
246

347
Include the bmi08x header
48+
449
``` c
550
#include "bmi08x.h"
651
```
752
Include the bmi085 variant header
53+
854
``` c
955
#include "bmi085.h"
1056
```
57+
1158
Enable the below macro in bmi08x_defs.h to use the BMI085 sensor feature
1259

1360
``` c
14-
/** Enable bmi085 sensor */
61+
/** \name enable bmi085 sensor */
1562
#ifndef BMI08X_ENABLE_BMI085
1663
#define BMI08X_ENABLE_BMI085 1
1764
#endif
1865
```
1966

20-
To initialize BMI085 for data synchronization, an instance of the bmi08x structure
21-
should be created. The following parameters are required to be updated in the
22-
structure by the user:
67+
To initialize BMI085 for data synchronization, an instance of the bmi08x structure should be created. The following parameters are required to be updated in the structure by the user:
2368

2469

2570
Parameters | Details
@@ -33,6 +78,9 @@ _delay_ms_ | delay
3378

3479

3580
##### _Initialize through SPI interface_
81+
82+
The following code is simplified code, for example no checking of return values is added, to make it easier to read the code.
83+
3684
``` c
3785

3886
struct bmi08x_dev bmi08xdev = {
@@ -44,109 +92,67 @@ struct bmi08x_dev bmi08xdev = {
4492
.delay_ms = user_delay_milli_sec
4593
};
4694

47-
48-
int8_t rslt;
49-
/* Initilaize int config instance */
50-
struct bmi08x_int_cfg int_config;
51-
/* Initilaize datasync config instance */
52-
struct bmi08x_data_sync_cfg sync_cfg;
95+
int16_t rslt;
5396

5497
/* Initialize bmi085 sensors (accel & gyro)*/
5598
rslt = bmi085_init(&bmi08xdev);
99+
/* Reset the accelerometer and wait for 1 ms - delay taken care inside the function */
100+
rslt = bmi08a_soft_reset(&bmi08xdev);
101+
102+
103+
/*! Max read/write length (maximum supported length is 32).
104+
To be set by the user */
105+
bmi08xdev.read_write_len = 32;
106+
/*set accel power mode */
107+
bmi08xdev.accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE;
108+
rslt = bmi08a_set_power_mode(&bmi08xdev);
109+
110+
bmi08xdev.gyro_cfg.power = BMI08X_GYRO_PM_NORMAL;
111+
bmi08g_set_power_mode(&bmi08xdev);
112+
113+
/* API uploads the bmi08x config file onto the device and wait for 150ms
114+
to enable the data synchronization - delay taken care inside the function */
115+
rslt = bmi085_apply_config_file(&bmi08xdev);
116+
117+
/*assign accel range setting*/
118+
bmi08xdev.accel_cfg.range = BMI085_ACCEL_RANGE_4G;
119+
/*assign gyro range setting*/
120+
bmi08xdev.gyro_cfg.range = BMI08X_GYRO_RANGE_2000_DPS;
121+
/*! Mode (0 = off, 1 = 400Hz, 2 = 1kHz, 3 = 2kHz) */
122+
sync_cfg.mode = BMI08X_ACCEL_DATA_SYNC_MODE_2000HZ;
123+
rslt = bmi085_configure_data_synchronization(sync_cfg, &bmi08xdev);
56124

57-
if (rslt == BMI08X_OK) {
58-
/* Reset the accelerometer*/
59-
rslt = bmi08a_soft_reset(&bmi08xdev);
60-
/* Wait for 1 ms - delay taken care inside the function */
61-
}
62-
63-
if (rslt == BMI08X_OK) {
64-
/* Assign accel power config*/
65-
bmi08xdev.accel_cfg.power = BMI08X_ACCEL_PM_ACTIVE;
66-
/* Set the accel power mode */
67-
rslt = bmi08a_set_power_mode(&bmi08xdev);
68-
/* Wait for 10ms to switch to normal mode - delay taken care inside the function */
69-
}
70-
71-
if (rslt == BMI08X_OK){
72-
/*Assign gyro power config*/
73-
bmi08xdev.gyro_cfg.power = BMI08X_GYRO_PM_NORMAL;
74-
/*set gyro power mode */
75-
rslt = bmi08g_set_power_mode(&bmi08xdev);
76-
/* Wait for 30ms to switch to normal mode -delay taken care inside the function */
77-
}
78-
79-
/* Upload synchronization configuration */
80-
if (rslt == BMI08X_OK) {
81-
/*! Max read/write length (maximum supported length is 32).
82-
To be set by the user */
83-
bmi08xdev.read_write_len = 8;
84-
85-
rslt = bmi085_apply_config_file(&bmi08xdev);
86-
/* Wait for 150ms to enable the data synchronization --delay taken care inside the function */
87-
}
88-
89-
if (rslt == BMI08X_OK){
90-
/* For data synchronization accel and gyro odr ,bandwidth will be configured based on the selected data sync mode.
91-
Configuration will be taken care by bmi085_configure_data_synchronization function */
92-
93-
/* Assign the accel range settings*/
94-
bmi08xdev.accel_cfg.range = BMI085_ACCEL_RANGE_4G;
95-
96-
/* Assign the gyro range settings */
97-
bmi08xdev.gyro_cfg.range = BMI08X_GYRO_RANGE_2000_DPS;
98-
99-
/*configure data synchronization mode */
100-
sync_cfg.mode = BMI08X_ACCEL_DATA_SYNC_MODE_2000HZ;
101-
102-
/* Enable data synchronization*/
103-
rslt = bmi085_configure_data_synchronization(sync_cfg, &bmi08xdev);
104-
105-
if (rslt == BMI08X_OK) {
106-
/*wait for 150 ms */
107-
bmi08xdev.delay_ms(BMI08X_ASIC_INIT_TIME_MS);
108-
}
109-
}
110-
111-
/* configure synchronization interrupt pins */
112-
113-
if (rslt == BMI08X_OK) {
114-
/*set accel interrupt pin configuration*/
115-
/*configure host data ready interrupt */
116-
int_config.accel_int_config_1.int_channel = BMI08X_INT_CHANNEL_1;
117-
int_config.accel_int_config_1.int_type = BMI08X_ACCEL_SYNC_INPUT;
118-
int_config.accel_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
119-
int_config.accel_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
120-
int_config.accel_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
121-
122-
/*configure Accel syncronization input interrupt pin */
123-
int_config.accel_int_config_2.int_channel = BMI08X_INT_CHANNEL_2;
124-
int_config.accel_int_config_2.int_type = BMI08X_ACCEL_SYNC_DATA_RDY_INT;
125-
int_config.accel_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
126-
int_config.accel_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
127-
int_config.accel_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
128-
129-
/*set gyro interrupt pin configuration*/
130-
int_config.gyro_int_config_1.int_channel = BMI08X_INT_CHANNEL_3;
131-
int_config.gyro_int_config_1.int_type = BMI08X_GYRO_DATA_RDY_INT;
132-
int_config.gyro_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
133-
int_config.gyro_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
134-
int_config.gyro_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
135-
136-
int_config.gyro_int_config_2.int_channel = BMI08X_INT_CHANNEL_4;
137-
int_config.gyro_int_config_2.int_type = BMI08X_GYRO_DATA_RDY_INT;
138-
int_config.gyro_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
139-
int_config.gyro_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
140-
int_config.gyro_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
141-
142-
/* Enable synchronization interrupt pin */
143-
rslt = bmi085_set_data_sync_int_config(&int_config, &bmi08xdev);
144-
145-
}
146-
/* User pin configuration */
147-
148-
/* Need to configure the accel data ready gpio pin as input */
149125

126+
/*set accel interrupt pin configuration*/
127+
/*configure host data ready interrupt */
128+
int_config.accel_int_config_1.int_channel = BMI08X_INT_CHANNEL_1;
129+
int_config.accel_int_config_1.int_type = BMI08X_ACCEL_SYNC_INPUT;
130+
int_config.accel_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
131+
int_config.accel_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
132+
int_config.accel_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
133+
134+
/*configure Accel syncronization input interrupt pin */
135+
int_config.accel_int_config_2.int_channel = BMI08X_INT_CHANNEL_2;
136+
int_config.accel_int_config_2.int_type = BMI08X_ACCEL_SYNC_DATA_RDY_INT;
137+
int_config.accel_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
138+
int_config.accel_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
139+
int_config.accel_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
140+
141+
/*set gyro interrupt pin configuration*/
142+
int_config.gyro_int_config_1.int_channel = BMI08X_INT_CHANNEL_3;
143+
int_config.gyro_int_config_1.int_type = BMI08X_GYRO_DATA_RDY_INT;
144+
int_config.gyro_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_ENABLE;
145+
int_config.gyro_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
146+
int_config.gyro_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
147+
148+
int_config.gyro_int_config_2.int_channel = BMI08X_INT_CHANNEL_4;
149+
int_config.gyro_int_config_2.int_type = BMI08X_GYRO_DATA_RDY_INT;
150+
int_config.gyro_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
151+
int_config.gyro_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
152+
int_config.gyro_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
153+
154+
/* Enable synchronization interrupt pin */
155+
rslt = bmi085_set_data_sync_int_config(&int_config, &bmi08xdev);
150156
```
151157
152158
#### Read out raw accel data
@@ -167,52 +173,4 @@ static struct bmi08x_sensor_data accel_bmi085;
167173
static struct bmi08x_sensor_data gyro_bmi085;
168174

169175
rslt = bmi085_get_synchronized_data(&accel_bmi085,&gyro_bmi085, &bmi08xdev);
170-
171-
```
172-
#### Disable synchronization feature
173-
```c
174-
175-
/*--------------------disable synchronization feature--------------------*/
176-
177-
/* Disable data synchronization */
178-
int8_t rslt;
179-
/* Initilaize datasync config instance */
180-
struct bmi08x_data_sync_cfg sync_cfg;
181-
/*turn off the sync feature*/
182-
sync_cfg.mode = BMI08X_ACCEL_DATA_SYNC_MODE_OFF;
183-
184-
rslt = bmi085_configure_data_synchronization(sync_cfg, &bmi08xdev);
185-
/* Wait for 150ms to enable the data synchronization --delay taken care inside the function */
186-
187-
/* configure synchronization interrupt pins */
188-
if (rslt == BMI08X_OK) {
189-
190-
int_config.accel_int_config_1.int_channel = BMI08X_INT_CHANNEL_1;
191-
int_config.accel_int_config_1.int_type = BMI08X_ACCEL_SYNC_INPUT ;
192-
int_config.accel_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
193-
int_config.accel_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
194-
int_config.accel_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
195-
196-
int_config.accel_int_config_2.int_channel = BMI08X_INT_CHANNEL_2;
197-
int_config.accel_int_config_2.int_type = BMI08X_ACCEL_SYNC_DATA_RDY_INT;
198-
int_config.accel_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
199-
int_config.accel_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
200-
int_config.accel_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
201-
202-
/*set gyro interrupt pin configuration*/
203-
int_config.gyro_int_config_1.int_channel = BMI08X_INT_CHANNEL_3;
204-
int_config.gyro_int_config_1.int_type = BMI08X_GYRO_DATA_RDY_INT;
205-
int_config.gyro_int_config_1.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
206-
int_config.gyro_int_config_1.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
207-
int_config.gyro_int_config_1.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
208-
209-
int_config.gyro_int_config_2.int_channel = BMI08X_INT_CHANNEL_4;
210-
int_config.gyro_int_config_2.int_type = BMI08X_GYRO_DATA_RDY_INT;
211-
int_config.gyro_int_config_2.int_pin_cfg.enable_int_pin = BMI08X_DISABLE;
212-
int_config.gyro_int_config_2.int_pin_cfg.lvl = BMI08X_INT_ACTIVE_HIGH;
213-
int_config.gyro_int_config_2.int_pin_cfg.output_mode = BMI08X_INT_MODE_PUSH_PULL;
214-
215-
/* Disable synchronization interrupt pin */
216-
rslt = bmi085_set_data_sync_int_config(&int_config, &bmi08xdev);
217-
}
218176
```

README.md

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,39 @@ _Note: By default, the interface is I2C._
7676
To initialize BMI085 sensors, an instance of the bmi08x structure should be created. The following parameters are required to be updated in the structure, by the user, to initialize bmi085 sensors.
7777

7878
Parameters | Details
79-
--------------|-----------------------------------
80-
_accel_id_ | Accel device address of I2C interface
81-
_gyro_id_ | Gyro device address of I2C interface
79+
--------------|-------------------------------------------------------------------------------------
80+
_accel_id_ | Accel device address of I2C interface (can be used to identify CSB1 pin in SPI mode)
81+
_gyro_id_ | Gyro device address of I2C interface (can be used to identify CSB2 pin in SPI mode)
8282
_intf_ | I2C or SPI
8383
_read_ | read through I2C/SPI interface
8484
_write_ | write through I2C/SPI interface
8585
_delay_ms_ | delay
8686

87+
As defined in _bmi08x_defs.h_, the _read_/_write_ functions must be implemented in such a way that they comply with the following template of a function declaration:
88+
89+
_typedef int8_t (*bmi08x_com_fptr_t)(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);_
90+
8791
##### _Initialize through SPI interface_
92+
In order to use SPI interface, the user has to implement dedicated SPI read/write functions, which could for example look like this:
93+
94+
_int8_t user_spi_write(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len);_
95+
96+
_int8_t user_spi_read(uint8_t cs_pin, uint8_t reg_addr, uint8_t *data, uint16_t len);_
97+
98+
Since the BMI08x sensor family has dedicated communication interfaces for gyro and accelerometer, two different chip select lines are required to retrieve all data from the sensor (see datasheet for details). The user can use the fields _accel_id_ and _gyro_id_ to provide an information to the generic SPI read/write function, which chip select to use.
99+
100+
When the sensorAPI functions call the _int8_t user_spi_write_ and _int8_t user_spi_read_ functions, they will pass the fields _accel_id_ or _gyro_id_ to the _cs_pin_ parameter.
101+
102+
In the example below it is assumed that on the MCU platform of the user, the pin for CSB1 (chip select for accelerometer and temperature sensor data) is defined as MCU_GPIO_BMI08X_CSB1 and the pin for CSB2 (gyro chip select) is defined as MCU_GPIO_BMI08X_CSB2.
103+
Thus the user need to provide the following values to the _bmi08x_dev_ structure and initialize SPI as follows.
104+
88105
``` c
89106

90107
int8_t rslt;
91108

92109
struct bmi08x_dev dev = {
93-
.accel_id = 0,
94-
.gyro_id = 0,
110+
.accel_id = MCU_GPIO_BMI08X_CSB1,
111+
.gyro_id = MCU_GPIO_BMI08X_CSB2,
95112
.intf = BMI08X_SPI_INTF,
96113
.read = user_spi_read,
97114
.write = user_spi_write,

0 commit comments

Comments
 (0)