Skip to content

Commit be0d71f

Browse files
committed
BMA421: Use internal FIFO for smoothing
1 parent 6171c9d commit be0d71f

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

src/drivers/Bma421.cpp

+53-16
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,37 @@ Bma421::Bma421(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaster}
3232
bma.intf_ptr = this;
3333
bma.delay_us = user_delay;
3434
bma.read_write_len = 16;
35+
bma.resolution = 12;
3536
}
3637

3738
void Bma421::Init() {
38-
if (not isResetOk)
39+
if (!isResetOk)
3940
return; // Call SoftReset (and reset TWI device) first!
4041

42+
// Initialize interface
4143
auto ret = bma423_init(&bma);
4244
if (ret != BMA4_OK)
4345
return;
4446

45-
switch(bma.chip_id) {
46-
case BMA423_CHIP_ID: deviceType = DeviceTypes::BMA421; break;
47-
case BMA425_CHIP_ID: deviceType = DeviceTypes::BMA425; break;
48-
default: deviceType = DeviceTypes::Unknown; break;
47+
// Identify chip by ID. The driver code has been modified to handle BMA421 as BMA423
48+
switch (bma.chip_id) {
49+
case BMA423_CHIP_ID:
50+
deviceType = DeviceTypes::BMA421;
51+
break;
52+
case BMA425_CHIP_ID:
53+
deviceType = DeviceTypes::BMA425;
54+
break;
55+
default:
56+
deviceType = DeviceTypes::Unknown;
57+
break;
4958
}
5059

60+
// Load proprietary firmware blob required for step counting engine
5161
ret = bma423_write_config_file(&bma);
5262
if (ret != BMA4_OK)
5363
return;
5464

55-
ret = bma4_set_interrupt_mode(BMA4_LATCH_MODE, &bma);
56-
if (ret != BMA4_OK)
57-
return;
58-
65+
// Enable step counter and accelerometer, disable step detector
5966
ret = bma423_feature_enable(BMA423_STEP_CNTR, 1, &bma);
6067
if (ret != BMA4_OK)
6168
return;
@@ -68,11 +75,21 @@ void Bma421::Init() {
6875
if (ret != BMA4_OK)
6976
return;
7077

78+
// Configure FIFO
79+
ret = bma4_set_fifo_config(BMA4_FIFO_ACCEL, 1, &bma);
80+
if (ret != BMA4_OK)
81+
return;
82+
fifo_frame.data = (uint8_t*) &fifo;
83+
fifo_frame.length = sizeof(fifo);
84+
fifo_frame.fifo_data_enable = BMA4_FIFO_A_ENABLE;
85+
fifo_frame.fifo_header_enable = 0;
86+
87+
// Configure accelerometer
7188
struct bma4_accel_config accel_conf;
72-
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
89+
accel_conf.odr = BMA4_OUTPUT_DATA_RATE_200HZ;
7390
accel_conf.range = BMA4_ACCEL_RANGE_2G;
7491
accel_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
75-
accel_conf.perf_mode = BMA4_CIC_AVG_MODE;
92+
accel_conf.perf_mode = BMA4_CONTINUOUS_MODE;
7693
ret = bma4_set_accel_config(&accel_conf, &bma);
7794
if (ret != BMA4_OK)
7895
return;
@@ -96,22 +113,42 @@ void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) {
96113
Bma421::Values Bma421::Process() {
97114
if (not isOk)
98115
return {};
99-
struct bma4_accel data;
100-
bma4_read_accel_xyz(&data, &bma);
101116

117+
// Dump entire FIFO into buffer
118+
bma4_read_fifo_data(&fifo_frame, &bma);
119+
// Decode FIFO frames in-place sequentially
120+
uint16_t length = 32; // Should be about 20 (200 Hz ODR / 10 Hz main loop)
121+
bma4_extract_accel((bma4_accel*) fifo, &length, &fifo_frame, &bma);
122+
123+
// Read step counter engine
102124
uint32_t steps = 0;
103125
bma423_step_counter_output(&steps, &bma);
104126

105-
int32_t temperature;
127+
// Read temperature sensor
128+
int32_t temperature = 0;
106129
bma4_get_temperature(&temperature, BMA4_DEG, &bma);
107130
temperature = temperature / 1000;
108131

132+
// Read sport activity mode
109133
uint8_t activity = 0;
110134
bma423_activity_output(&activity, &bma);
111135

112-
// X and Y axis are swapped because of the way the sensor is mounted in the PineTime
113-
return {steps, data.y, data.x, data.z};
136+
// Compute averages of FIFO
137+
int16_t avgs[3] = {0};
138+
for (uint8_t i = 0; i < length; i++) {
139+
// X and Y axis are swapped because of the way the sensor is mounted in the PineTime
140+
int16_t swap = fifo[i][0];
141+
fifo[i][0] = fifo[i][1];
142+
fifo[i][1] = swap;
143+
for (uint8_t j = 0; j < 3; j++)
144+
avgs[j] += fifo[i][j];
145+
}
146+
for (uint8_t j = 0; j < 3; j++)
147+
avgs[j] /= length;
148+
149+
return {steps, avgs[0], avgs[1], avgs[2]};
114150
}
151+
115152
bool Bma421::IsOk() const {
116153
return isOk;
117154
}

src/drivers/Bma421.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ namespace Pinetime {
66
class TwiMaster;
77
class Bma421 {
88
public:
9-
enum class DeviceTypes : uint8_t {
10-
Unknown,
11-
BMA421,
12-
BMA425
13-
};
9+
enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 };
1410
struct Values {
1511
uint32_t steps;
1612
int16_t x;
@@ -42,6 +38,8 @@ namespace Pinetime {
4238
TwiMaster& twiMaster;
4339
uint8_t deviceAddress = 0x18;
4440
struct bma4_dev bma;
41+
struct bma4_fifo_frame fifo_frame;
42+
int16_t fifo[32][3] = {0};
4543
bool isOk = false;
4644
bool isResetOk = false;
4745
DeviceTypes deviceType = DeviceTypes::Unknown;

0 commit comments

Comments
 (0)