Skip to content

Commit ee08a03

Browse files
committed
Use single dataReady() method, instead of accelDataReady/gyroDataReady
This method is a bit more flexible. There is a version with no parameters, which will return true if all enabled sensors have new data. There is one overload, that takes a single 'flags' parameter, which returns true if all enabled *and* selected sensors have new data. Sensors are selectable through bit flags. For example; CurieIMU.dataReady() : this will return true if both the accel and gyro are enabled, and both have new data ready. CurieIMU.dataReady(ACCEL | GYRO) : this will return true if both the accel and gyro are enabled, and both have new data ready. CurieIMU.dataReady(GYRO) : this will return true if the gyro is enabled and has new data ready. CurieIMU.dataReady(ACCEL) : this will return true if the accel is enabled and has new data ready. This also involved changing the 'begin' method to allow selective enabling of sensors, e.g. CurieIMU.begin() : same as it always has, initializes IMU, enabling both accel and gyro CurieIMU.begin(ACCEL | GYRO) : initializes IMU, enabling both accel and gyro CurieIMU.begin(ACCEL) : initializes IMU, enabling accel only
1 parent fb57800 commit ee08a03

File tree

5 files changed

+138
-55
lines changed

5 files changed

+138
-55
lines changed

Diff for: libraries/CurieIMU/keywords.txt

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CurieIMUClass KEYWORD1
1414

1515
begin KEYWORD1
1616

17+
dataReady KEYWORD1
1718
getGyroRate KEYWORD1
1819
setGyroRate KEYWORD1
1920
getAccelerometerRate KEYWORD1
@@ -84,6 +85,9 @@ CurieIMU KEYWORD2
8485
# Constants (LITERAL1)
8586
#######################################
8687

88+
ACCEL LITERAL1
89+
GYRO LITERAL1
90+
8791
X_AXIS LITERAL1
8892
Y_AXIS LITERAL1
8993
Z_AXIS LITERAL1

Diff for: libraries/CurieIMU/src/BMI160.cpp

+46-32
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,22 @@ uint8_t BMI160Class::reg_read_bits(uint8_t reg, unsigned pos, unsigned len)
7878
return b;
7979
}
8080

81+
int BMI160Class::isBitSet(uint8_t value, unsigned bit)
82+
{
83+
return value & (1 << bit);
84+
}
85+
8186
/******************************************************************************/
8287

8388
/** Power on and prepare for general usage.
8489
* This will activate the device and take it out of sleep mode (which must be done
8590
* after start-up). This function also sets both the accelerometer and the gyroscope
8691
* to default range settings, namely +/- 2g and +/- 250 degrees/sec.
8792
*/
88-
void BMI160Class::initialize()
93+
void BMI160Class::initialize(unsigned int flags)
8994
{
95+
sensors_enabled = 0;
96+
9097
/* Issue a soft-reset to bring the device into a clean state */
9198
reg_write(BMI160_RA_CMD, BMI160_CMD_SOFT_RESET);
9299
delay(1);
@@ -95,26 +102,36 @@ void BMI160Class::initialize()
95102
reg_read(0x7F);
96103
delay(1);
97104

98-
/* Power up the accelerometer */
99-
reg_write(BMI160_RA_CMD, BMI160_CMD_ACC_MODE_NORMAL);
100-
delay(1);
101-
/* Wait for power-up to complete */
102-
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
105+
if (flags & ACCEL) {
106+
/* Power up the accelerometer */
107+
reg_write(BMI160_RA_CMD, BMI160_CMD_ACC_MODE_NORMAL);
108+
delay(1);
109+
110+
/* Wait for power-up to complete */
111+
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
103112
BMI160_ACC_PMU_STATUS_BIT,
104113
BMI160_ACC_PMU_STATUS_LEN))
114+
delay(1);
115+
116+
sensors_enabled |= ACCEL;
117+
}
118+
119+
if (flags & GYRO) {
120+
/* Power up the gyroscope */
121+
reg_write(BMI160_RA_CMD, BMI160_CMD_GYR_MODE_NORMAL);
105122
delay(1);
106123

107-
/* Power up the gyroscope */
108-
reg_write(BMI160_RA_CMD, BMI160_CMD_GYR_MODE_NORMAL);
109-
delay(1);
110-
/* Wait for power-up to complete */
111-
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
124+
/* Wait for power-up to complete */
125+
while (0x1 != reg_read_bits(BMI160_RA_PMU_STATUS,
112126
BMI160_GYR_PMU_STATUS_BIT,
113127
BMI160_GYR_PMU_STATUS_LEN))
114-
delay(1);
128+
delay(1);
129+
130+
sensors_enabled |= GYRO;
131+
}
115132

116-
setFullScaleGyroRange(BMI160_GYRO_RANGE_250);
117-
setFullScaleAccelRange(BMI160_ACCEL_RANGE_2G);
133+
setFullScaleGyroRange(BMI160_GYRO_RANGE_250, 250.0f);
134+
setFullScaleAccelRange(BMI160_ACCEL_RANGE_2G, 2.0f);
118135

119136
/* Only PIN1 interrupts currently supported - map all interrupts to PIN1 */
120137
reg_write(BMI160_RA_INT_MAP_0, 0xFF);
@@ -131,6 +148,17 @@ uint8_t BMI160Class::getDeviceID() {
131148
return reg_read(BMI160_RA_CHIP_ID);
132149
}
133150

151+
/* Checks if the specified sensors are enabled (sensors are specified using
152+
* bit flags defined by CurieIMUSensor enum). If 0 is passed, checks if *any*
153+
* sensors are enabled */
154+
bool BMI160Class::isEnabled(unsigned int sensors)
155+
{
156+
if (sensors == 0)
157+
return sensors_enabled > 0;
158+
159+
return (sensors_enabled & sensors) > 0;
160+
}
161+
134162
/** Verify the SPI connection.
135163
* Make sure the device is connected and responds as expected.
136164
* @return True if connection is valid, false otherwise
@@ -330,10 +358,11 @@ uint8_t BMI160Class::getFullScaleGyroRange() {
330358
* @param range New full-scale gyroscope range value
331359
* @see getFullScaleGyroRange()
332360
*/
333-
void BMI160Class::setFullScaleGyroRange(uint8_t range) {
361+
void BMI160Class::setFullScaleGyroRange(uint8_t range, float real) {
334362
reg_write_bits(BMI160_RA_GYRO_RANGE, range,
335363
BMI160_GYRO_RANGE_SEL_BIT,
336364
BMI160_GYRO_RANGE_SEL_LEN);
365+
gyro_range = real;
337366
}
338367

339368
/** Get full-scale accelerometer range.
@@ -362,10 +391,11 @@ uint8_t BMI160Class::getFullScaleAccelRange() {
362391
* @see getFullScaleAccelRange()
363392
* @see BMI160AccelRange
364393
*/
365-
void BMI160Class::setFullScaleAccelRange(uint8_t range) {
394+
void BMI160Class::setFullScaleAccelRange(uint8_t range, float real) {
366395
reg_write_bits(BMI160_RA_ACCEL_RANGE, range,
367396
BMI160_ACCEL_RANGE_SEL_BIT,
368397
BMI160_ACCEL_RANGE_SEL_LEN);
398+
accel_range = real;
369399
}
370400

371401
/** Get accelerometer offset compensation enabled value.
@@ -2386,19 +2416,3 @@ uint8_t BMI160Class::getRegister(uint8_t reg) {
23862416
void BMI160Class::setRegister(uint8_t reg, uint8_t data) {
23872417
reg_write(reg, data);
23882418
}
2389-
2390-
/** Check if new gyroscope data is available
2391-
* @return True if new data is available, else false.
2392-
*/
2393-
bool BMI160Class::gyroDataReady()
2394-
{
2395-
return reg_read_bits(BMI160_RA_STATUS, BMI160_STATUS_DRDY_GYR, 1);
2396-
}
2397-
2398-
/** Check if new accelerometer data is available
2399-
* @return True if new data is available, else false.
2400-
*/
2401-
bool BMI160Class::accelDataReady()
2402-
{
2403-
return reg_read_bits(BMI160_RA_STATUS, BMI160_STATUS_DRDY_ACC, 1);
2404-
}

Diff for: libraries/CurieIMU/src/BMI160.h

+15-5
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,12 @@ THE SOFTWARE.
267267

268268
#define BMI160_RA_CMD 0x7E
269269

270+
/* Bit flags for selecting individual sensors */
271+
typedef enum {
272+
GYRO = 0x1,
273+
ACCEL = 0x2
274+
} CurieIMUSensor;
275+
270276
/**
271277
* Interrupt Latch Mode options
272278
* @see setInterruptLatch()
@@ -471,9 +477,10 @@ typedef enum {
471477

472478
class BMI160Class {
473479
public:
474-
void initialize();
480+
void initialize(unsigned int flags);
475481
bool testConnection();
476482

483+
bool isEnabled(unsigned int sensors);
477484
uint8_t getGyroRate();
478485
void setGyroRate(uint8_t rate);
479486

@@ -487,9 +494,9 @@ class BMI160Class {
487494
void setAccelDLPFMode(uint8_t bandwidth);
488495

489496
uint8_t getFullScaleGyroRange();
490-
void setFullScaleGyroRange(uint8_t range);
497+
void setFullScaleGyroRange(uint8_t range, float real);
491498
uint8_t getFullScaleAccelRange();
492-
void setFullScaleAccelRange(uint8_t range);
499+
void setFullScaleAccelRange(uint8_t range, float real);
493500

494501
void autoCalibrateGyroOffset();
495502
bool getGyroOffsetEnabled();
@@ -640,6 +647,7 @@ class BMI160Class {
640647

641648
uint8_t getDeviceID();
642649

650+
int isBitSet(uint8_t value, unsigned bit);
643651
uint8_t getRegister(uint8_t reg);
644652
void setRegister(uint8_t reg, uint8_t data);
645653

@@ -653,8 +661,10 @@ class BMI160Class {
653661
void setInterruptLatch(uint8_t latch);
654662
void resetInterrupt();
655663

656-
bool gyroDataReady();
657-
bool accelDataReady();
664+
/* Use a bitmask to track which sensors are enabled */
665+
unsigned sensors_enabled;
666+
float accel_range;
667+
float gyro_range;
658668

659669
protected:
660670
virtual int serial_buffer_transfer(uint8_t *buf, unsigned tx_cnt, unsigned rx_cnt) = 0;

Diff for: libraries/CurieIMU/src/CurieIMU.cpp

+68-15
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
* on the Curie module, before calling BMI160::initialize() to activate the
3333
* BMI160 accelerometer and gyroscpoe with default settings.
3434
*/
35-
bool CurieIMUClass::begin()
35+
36+
bool CurieIMUClass::configure_imu(unsigned int sensors)
3637
{
3738
ss_spi_init(SPI_SENSING_1, 2000, SPI_BUSMODE_0, SPI_8_BIT, SPI_SE_1);
3839

@@ -41,7 +42,7 @@ bool CurieIMUClass::begin()
4142
serial_buffer_transfer(&dummy_reg, 1, 1);
4243

4344
/* The SPI interface is ready - now invoke the base class initialization */
44-
BMI160Class::initialize();
45+
initialize(sensors);
4546

4647
/** Verify the SPI connection.
4748
* MakgetGyroRatee sure the device is connected and responds as expected.
@@ -50,16 +51,66 @@ bool CurieIMUClass::begin()
5051
if (CURIE_IMU_CHIP_ID != getDeviceID())
5152
return false;
5253

53-
accel_range = (float) getAccelerometerRange();
54-
gyro_range = (float) getGyroRange();
5554
return true;
5655
}
5756

57+
bool CurieIMUClass::begin()
58+
{
59+
return configure_imu(GYRO | ACCEL);
60+
}
61+
62+
bool CurieIMUClass::begin(unsigned int sensors)
63+
{
64+
return configure_imu(sensors);
65+
}
66+
5867
void CurieIMUClass::end()
5968
{
6069
ss_spi_disable(SPI_SENSING_1);
6170
}
6271

72+
bool CurieIMUClass::dataReady()
73+
{
74+
uint8_t stat;
75+
76+
/* If no sensors are enabled */
77+
if (!isEnabled(0))
78+
return false;
79+
80+
/* Read status register */
81+
stat = getRegister(BMI160_RA_STATUS);
82+
83+
if (isEnabled(GYRO) && !isBitSet(stat, BMI160_STATUS_DRDY_GYR))
84+
return false;
85+
86+
if (isEnabled(ACCEL) && !isBitSet(stat, BMI160_STATUS_DRDY_ACC))
87+
return false;
88+
89+
return true;
90+
}
91+
92+
bool CurieIMUClass::dataReady(unsigned int sensors)
93+
{
94+
uint8_t stat;
95+
96+
/* If no sensors enabled, or no data requested */
97+
if (sensors == 0 || !isEnabled(0))
98+
return false;
99+
100+
/* Read status register */
101+
stat = getRegister(BMI160_RA_STATUS);
102+
103+
if ((sensors & GYRO) && isEnabled(GYRO) &&
104+
!isBitSet(stat, BMI160_STATUS_DRDY_GYR))
105+
return false;
106+
107+
if ((sensors & ACCEL) && isEnabled(ACCEL) &&
108+
!isBitSet(stat, BMI160_STATUS_DRDY_ACC))
109+
return false;
110+
111+
return true;
112+
}
113+
63114
int CurieIMUClass::getGyroRate()
64115
{
65116
int rate;
@@ -227,25 +278,26 @@ int CurieIMUClass::getGyroRange()
227278
void CurieIMUClass::setGyroRange(int range)
228279
{
229280
BMI160GyroRange bmiRange;
281+
float real;
230282

231283
if (range >= 2000) {
232284
bmiRange = BMI160_GYRO_RANGE_2000;
233-
gyro_range = 2000.0f;
285+
real = 2000.0f;
234286
} else if (range >= 1000) {
235287
bmiRange = BMI160_GYRO_RANGE_1000;
236-
gyro_range = 1000.0f;
288+
real = 1000.0f;
237289
} else if (range >= 500) {
238290
bmiRange = BMI160_GYRO_RANGE_500;
239-
gyro_range = 500.0f;
291+
real = 500.0f;
240292
} else if (range >= 250) {
241293
bmiRange = BMI160_GYRO_RANGE_250;
242-
gyro_range = 250.0f;
294+
real = 250.0f;
243295
} else {
244296
bmiRange = BMI160_GYRO_RANGE_125;
245-
gyro_range = 125.0f;
297+
real = 125.0f;
246298
}
247299

248-
setFullScaleGyroRange(bmiRange);
300+
setFullScaleGyroRange(bmiRange, real);
249301
}
250302

251303
int CurieIMUClass::getAccelerometerRange()
@@ -277,22 +329,23 @@ int CurieIMUClass::getAccelerometerRange()
277329
void CurieIMUClass::setAccelerometerRange(int range)
278330
{
279331
BMI160AccelRange bmiRange;
332+
float real;
280333

281334
if (range <= 2) {
282335
bmiRange = BMI160_ACCEL_RANGE_2G;
283-
accel_range = 2.0f;
336+
real = 2.0f;
284337
} else if (range <= 4) {
285338
bmiRange = BMI160_ACCEL_RANGE_4G;
286-
accel_range = 4.0f;
339+
real = 4.0f;
287340
} else if (range <= 8) {
288341
bmiRange = BMI160_ACCEL_RANGE_8G;
289-
accel_range = 8.0f;
342+
real = 8.0f;
290343
} else {
291344
bmiRange = BMI160_ACCEL_RANGE_16G;
292-
accel_range = 16.0f;
345+
real = 16.0f;
293346
}
294347

295-
setFullScaleAccelRange(bmiRange);
348+
setFullScaleAccelRange(bmiRange, real);
296349
}
297350

298351
void CurieIMUClass::autoCalibrateGyroOffset()

Diff for: libraries/CurieIMU/src/CurieIMU.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,13 @@ class CurieIMUClass : public BMI160Class {
9494
friend void bmi160_pin1_isr(void);
9595

9696
public:
97+
bool begin(unsigned int sensors);
9798
bool begin(void);
9899
void end(void);
99100

101+
bool dataReady();
102+
bool dataReady(unsigned int sensors);
103+
100104
// supported values: 25, 50, 100, 200, 400, 800, 1600, 3200 (Hz)
101105
int getGyroRate();
102106
void setGyroRate(int rate);
@@ -207,11 +211,9 @@ class CurieIMUClass : public BMI160Class {
207211
void detachInterrupt(void);
208212

209213
private:
214+
bool configure_imu(unsigned int sensors);
210215
int serial_buffer_transfer(uint8_t *buf, unsigned tx_cnt, unsigned rx_cnt);
211216

212-
float accel_range;
213-
float gyro_range;
214-
215217
float getFreefallDetectionThreshold();
216218
void setFreefallDetectionThreshold(float threshold);
217219
float getShockDetectionThreshold();

0 commit comments

Comments
 (0)