Skip to content

Commit 01504d5

Browse files
cvejlbofacchinm
authored andcommitted
Add BMI270 and BMM150 data collection example
1 parent 9a74a01 commit 01504d5

File tree

4 files changed

+721
-3
lines changed

4 files changed

+721
-3
lines changed
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
#include "NDP.h"
2+
3+
#include "BMI270_Init.h"
4+
5+
void ledBlueOn(char* label) {
6+
nicla::leds.begin();
7+
nicla::leds.setColor(blue);
8+
delay(200);
9+
nicla::leds.setColor(off);
10+
Serial.println(label);
11+
nicla::leds.end();
12+
}
13+
14+
void ledGreenOn() {
15+
nicla::leds.begin();
16+
nicla::leds.setColor(green);
17+
delay(200);
18+
nicla::leds.setColor(off);
19+
nicla::leds.end();
20+
}
21+
22+
void ledRedBlink() {
23+
while (1) {
24+
nicla::leds.begin();
25+
nicla::leds.setColor(red);
26+
delay(200);
27+
nicla::leds.setColor(off);
28+
delay(200);
29+
nicla::leds.end();
30+
}
31+
}
32+
33+
uint8_t sensor_all_bytes[16]={0};
34+
35+
bool debugTrace = false;
36+
37+
void setup() {
38+
39+
Serial.begin(115200);
40+
nicla::begin();
41+
nicla::disableLDO();
42+
nicla::leds.begin();
43+
44+
NDP.onError(ledRedBlink);
45+
NDP.onMatch(ledBlueOn);
46+
NDP.onEvent(ledGreenOn);
47+
Serial.println("Loading synpackages");
48+
NDP.begin("mcu_fw_120_v91.synpkg");
49+
NDP.load("dsp_firmware_v91.synpkg");
50+
NDP.load("alexa_334_NDP120_B0_v11_v91.synpkg");
51+
Serial.println("packages loaded");
52+
NDP.getInfo();
53+
Serial.println("Configure clock");
54+
NDP.turnOnMicrophone();
55+
NDP.interrupts();
56+
57+
58+
// Basic master SPI controls
59+
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
60+
uint8_t s = 0; // flag for error in communication with motion sensor
61+
uint8_t targetDevice = 0; // "0" or "1". "0": BMI270. "1": BMM150.
62+
uint8_t ndpCSPISpeedFactor = 4; // this factor can take values 1, 2, 3 or 4. This is a division factor from NDP120 internal
63+
// clock. The larger the factor, the slower the CSPI speed - which should ease compatibility with slow SPI targets.
64+
uint32_t bmi_sensor_address = 0;
65+
uint16_t number_of_bytes = 0;
66+
uint32_t *bmi270_initialization_pointer;
67+
68+
// IMPORTANT: All reads to register address in BMI270 will use "Reg4Read" for method. That's because readout
69+
// from BMI270 using SPI interfaace will come with 1 dummy byte pre-pended to any actual content.
70+
// That is, whenever a 1 byte content from BMI270 is to be read, it will come through the BMI270 SPI interface
71+
// prepended by 1 junk byte and 1 dummy byte, before the actual byte of interest comes.
72+
// BMI270 Initiliztion file to be used:
73+
bmi270_initialization_pointer = (uint32_t*)bmi270_maximum_fifo_config_file;
74+
number_of_bytes = sizeof(bmi270_maximum_fifo_config_file);
75+
76+
//Reading BMI270 Chip ID (twice...to put the device in SPI mode)
77+
bmi_sensor_address = 0x00;
78+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
79+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
80+
Serial.print("BMI270 chip ID is (expected is 0x24): 0x");
81+
Serial.println(sensor_all_bytes[0], HEX);
82+
delay(100);
83+
84+
//Initialization process. Following BMI270 initialization process: page 18/150
85+
// disable PWR_CONF.adv_power_save
86+
bmi_sensor_address = 0x7c;
87+
sensor_all_bytes[0] = 0x02;
88+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
89+
delay(20); //delay 20ms much longer than reqired 450us
90+
91+
// prepare config load INIT_CTRL = 0x00
92+
bmi_sensor_address = 0x59;
93+
sensor_all_bytes[0] = 0x00;
94+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
95+
delay(20); //delay 20ms much longer than 450us
96+
97+
// Push bmi270_maximum_fifo_config_file[] to initialize BMI270
98+
Serial.print("BMI270 config file has number of bytes equal to: ");
99+
Serial.println(number_of_bytes);
100+
101+
// burst write to reg INIT_DATA Start with byte 0
102+
// timing the process of pushing all initialization
103+
Serial.print("\nStarting the upload of bmi270 config file ...");
104+
int initialization_process_time = 0;
105+
initialization_process_time = millis();
106+
if (debugTrace) {
107+
Serial.println("Writing data");
108+
for (int i=0; i<10; i++){
109+
Serial.print("file index: ");
110+
Serial.print(i);
111+
Serial.print("file value: ");
112+
Serial.println(bmi270_maximum_fifo_config_file[i],HEX);
113+
}
114+
}
115+
delay(20);
116+
117+
bmi_sensor_address = 0x5e;
118+
s = NDP.transparentNiclaVoiceBMI270SensorDataInitialization(targetDevice, ndpCSPISpeedFactor, number_of_bytes, bmi270_maximum_fifo_config_file);
119+
initialization_process_time = (millis() - initialization_process_time)/1000.0;
120+
Serial.println("\nDone with initialization ...");
121+
if (debugTrace) {
122+
Serial.print("\nTime to upload initialization file (seconds): ");
123+
Serial.println(initialization_process_time);
124+
}
125+
delay(20); //delay 20ms much longer than 450us
126+
127+
// complete config load
128+
//////////////////////////////////////////////////////////////
129+
bmi_sensor_address = 0x59;
130+
sensor_all_bytes[0] = 0x01;
131+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
132+
133+
///////////////////////////////////////////
134+
delay(20); //delay 20ms much longer than 450us
135+
// check initialization status
136+
// read INTERNAL_STATUS
137+
bmi_sensor_address = 0x21;
138+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
139+
Serial.print("BMI270 Status Register at address 0x21 is (expected is 0x01): 0x");
140+
Serial.println(sensor_all_bytes[0], HEX);
141+
142+
bmi_sensor_address = 0x59;
143+
sensor_all_bytes[0] = 0x00;
144+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
145+
146+
bmi_sensor_address = 0x5b;
147+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 2, sensor_all_bytes);
148+
if (debugTrace) {
149+
Serial.println("Before writing on 5b/c ");
150+
Serial.println(sensor_all_bytes[0], HEX);
151+
Serial.println(sensor_all_bytes[1], HEX);
152+
}
153+
sensor_all_bytes[0] = 0x00;
154+
sensor_all_bytes[1] = 0x00;
155+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 2, sensor_all_bytes);
156+
delay(20);
157+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 2, sensor_all_bytes);
158+
if (debugTrace) {
159+
Serial.println("After resetting on 5b/c ");
160+
Serial.println(sensor_all_bytes[0], HEX);
161+
Serial.println(sensor_all_bytes[1], HEX);
162+
}
163+
164+
bmi_sensor_address = 0x5e;
165+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 10, sensor_all_bytes);
166+
if (debugTrace) {
167+
Serial.println("Reading data");
168+
for (int i = 0; i < 10; i++){
169+
Serial.println(sensor_all_bytes[i], HEX);
170+
}
171+
}
172+
bmi_sensor_address = 0x5b;
173+
sensor_all_bytes[0] = 0x0F;
174+
sensor_all_bytes[1] = 0x09;
175+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 2, sensor_all_bytes);
176+
delay(20);
177+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 2, sensor_all_bytes);
178+
if (debugTrace) {
179+
Serial.println("After resetting 9F (last 10) on 5b/c ");
180+
Serial.println(sensor_all_bytes[0], HEX);
181+
Serial.println(sensor_all_bytes[1], HEX);
182+
}
183+
184+
bmi_sensor_address = 0x5e;
185+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 10, sensor_all_bytes);
186+
if (debugTrace) {
187+
Serial.println("Reading data");
188+
for (int i = 0; i < 10; i++){
189+
Serial.println(sensor_all_bytes[i], HEX);
190+
}
191+
}
192+
193+
// configuring device to normal power mode with both Accelerometer and gyroscope working
194+
////////////////////////////////////////////////////////////////////////////////////////
195+
// setting PWR_CTRL
196+
bmi_sensor_address = 0x7d;
197+
sensor_all_bytes[0] = 0x0e;
198+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
199+
delay(20); //delay 20ms much longer than 450us
200+
201+
//ACC_CONF
202+
////////////
203+
bmi_sensor_address = 0x40;
204+
sensor_all_bytes[0] = 0xa8;
205+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
206+
delay(20); //delay 20ms much longer than 450us
207+
208+
//ACC_RANGE
209+
////////////
210+
bmi_sensor_address = 0x41;
211+
sensor_all_bytes[0] = 0x00; /* +* 2g */
212+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
213+
delay(20); //delay 20ms much longer than 450us
214+
215+
//GYR_CONF
216+
//////////
217+
bmi_sensor_address = 0x42;
218+
sensor_all_bytes[0] = 0xa9;
219+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
220+
delay(20); //delay 20ms much longer than 450us
221+
222+
//GYR_RANGE
223+
//////////
224+
bmi_sensor_address = 0x43;
225+
sensor_all_bytes[0]= 0x11; /* +-250 */
226+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
227+
delay(20); //delay 20ms much longer than 450us
228+
229+
//PWR_CONF
230+
////////////
231+
bmi_sensor_address = 0x7c;
232+
sensor_all_bytes[0] = 0x02;
233+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 1, sensor_all_bytes);
234+
delay(20); //delay 20ms much longer than 450us
235+
236+
237+
///////////////////////////////////////////// BMM 150 test /////////////////////////////////////////////////////
238+
//Reading BMM 150 CHip ID
239+
///////////////////////////////////////////
240+
uint32_t bmm_sensor_address = 0;
241+
targetDevice = 1; // 0, 1 possible values. 0: ST or BMI270. 1: BMM150
242+
243+
bmm_sensor_address = 0x4B;
244+
sensor_all_bytes[0] = 0x1; // Is it equivalent to 0x01?
245+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmm_sensor_address, 1, sensor_all_bytes);
246+
247+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmm_sensor_address, 1, sensor_all_bytes);
248+
Serial.print("BMM150 power control byte at address 0x4B is (expected is 0x01): 0x");
249+
Serial.println(sensor_all_bytes[0], HEX);
250+
251+
bmm_sensor_address = 0x4C;
252+
sensor_all_bytes[0] = 0x00; // Is it in sleep mode by default?
253+
s = NDP.transparentNiclaVoiceSensorRegWrite(targetDevice, ndpCSPISpeedFactor, bmm_sensor_address, 1, sensor_all_bytes);
254+
255+
bmm_sensor_address = 0x40;
256+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmm_sensor_address, 1, sensor_all_bytes);
257+
Serial.print("BMM150 power chip ID at address 0x40 is (expected is 0x32): 0x");
258+
Serial.println(sensor_all_bytes[0], HEX);
259+
}
260+
261+
#define NUM_LOOPS_PER_SENSOR 15
262+
void loop() {
263+
uint8_t s = 0; // flag for error in communication with motion sensor
264+
uint32_t bmi_sensor_address = 0, bmm_sensor_address = 0;
265+
uint8_t targetDevice = 0; // 0 or 1. 0: BMI270. 1: BMM150
266+
uint8_t ndpCSPISpeedFactor = 4; // this factor can take values 1, 2, 3 or 4. This is a division factor from NDP120 reference
267+
static int loopCounter = 0;
268+
269+
//read one accel and one gyro datum at a time
270+
//read acc_x_7_0 and acc_x_15_8
271+
int16_t x_acc, y_acc, z_acc, x_gyr, y_gyr, z_gyr ;
272+
int16_t x_mag, y_mag, z_mag, hall;
273+
if (loopCounter < NUM_LOOPS_PER_SENSOR) {
274+
if (!loopCounter) {
275+
Serial.println("\nTesting Nicla Voice IMU Sensor");
276+
}
277+
bmi_sensor_address = 0x0C;
278+
279+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmi_sensor_address, 16, sensor_all_bytes);
280+
if (debugTrace) {
281+
Serial.print("number of bytes outputted: ");
282+
Serial.println(s);
283+
}
284+
x_acc = (0x0000 | sensor_all_bytes[0] | sensor_all_bytes[1] << 8);
285+
y_acc = (0x0000 | sensor_all_bytes[2] | sensor_all_bytes[3] << 8);
286+
z_acc = (0x0000 | sensor_all_bytes[4] | sensor_all_bytes[5] << 8);
287+
x_gyr = (0x0000 | sensor_all_bytes[6] | sensor_all_bytes[7] << 8);
288+
y_gyr = (0x0000 | sensor_all_bytes[8] | sensor_all_bytes[9] << 8);
289+
z_gyr = (0x0000 | sensor_all_bytes[10] | sensor_all_bytes[11]<< 8);
290+
291+
Serial.print("\rBMI270 data: Acc X, Acc Y, Acc Z ");
292+
Serial.print(x_acc);
293+
Serial.print(" , ");
294+
Serial.print(y_acc);
295+
Serial.print(" , ");
296+
Serial.print(z_acc);
297+
Serial.print(" , ");
298+
Serial.print(x_gyr);
299+
Serial.print(" , ");
300+
Serial.print(y_gyr);
301+
Serial.print(" , ");
302+
Serial.print(z_gyr);
303+
Serial.println();
304+
} else if (loopCounter == NUM_LOOPS_PER_SENSOR) {
305+
Serial.println("\nTesting Nicla Voice Magnetometer");
306+
} else { // loopCounter > NUM_LOOPS_PER_SENSOR
307+
bmm_sensor_address = 0x42;
308+
targetDevice = 1;
309+
s = NDP.transparentNiclaVoiceSensorRegRead(targetDevice, ndpCSPISpeedFactor, bmm_sensor_address, 8, sensor_all_bytes);
310+
if (debugTrace) {
311+
Serial.print("number of bytes outputted: ");
312+
Serial.println(s);
313+
314+
for (int index = 0; index < 8; index++){
315+
Serial.println(sensor_all_bytes[index], HEX);
316+
}
317+
}
318+
319+
x_mag = (0x0000 | sensor_all_bytes[0] >> 3 | sensor_all_bytes[1] << 5);
320+
y_mag = (0x0000 | sensor_all_bytes[2] >> 3 | sensor_all_bytes[3] << 5);
321+
z_mag = (0x0000 | sensor_all_bytes[4] >> 1 | sensor_all_bytes[5] << 7);
322+
hall = (0x0000 | sensor_all_bytes[6] >> 2 | sensor_all_bytes[7] << 6);
323+
324+
Serial.print("\rBMM150 data: Mag X, Mag Y, Mag Z, Hall ");
325+
Serial.print(x_mag);
326+
Serial.print(" , ");
327+
Serial.print(y_mag);
328+
Serial.print(" , ");
329+
Serial.print(z_mag);
330+
Serial.print(" , ");
331+
Serial.print(hall);
332+
Serial.println();
333+
}
334+
delay(100);
335+
336+
// switch to other sensor again
337+
if (++loopCounter > 2 * NUM_LOOPS_PER_SENSOR) {
338+
loopCounter = 0;
339+
}
340+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Configuration file for BMI270
2+
const uint8_t bmi270_maximum_fifo_config_file[] = {
3+
0xc8, 0x2e, 0x00, 0x2e, 0x80, 0x2e, 0x1a, 0x00, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00,
4+
0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0xc8, 0x2e, 0x00, 0x2e, 0x90, 0x32, 0x21, 0x2e, 0x59, 0xf5,
5+
0x10, 0x30, 0x21, 0x2e, 0x6a, 0xf5, 0x1a, 0x24, 0x22, 0x00, 0x80, 0x2e, 0x3b, 0x00, 0xc8, 0x2e, 0x44, 0x47, 0x22,
6+
0x00, 0x37, 0x00, 0xa4, 0x00, 0xff, 0x0f, 0xd1, 0x00, 0x07, 0xad, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1,
7+
0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00,
8+
0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x80, 0x2e, 0x00, 0xc1, 0x00, 0x00,
9+
0x00, 0x00, 0x00, 0x00, 0x11, 0x24, 0xfc, 0xf5, 0x80, 0x30, 0x40, 0x42, 0x50, 0x50, 0x00, 0x30, 0x12, 0x24, 0xeb,
10+
0x00, 0x03, 0x30, 0x00, 0x2e, 0xc1, 0x86, 0x5a, 0x0e, 0xfb, 0x2f, 0x21, 0x2e, 0xfc, 0xf5, 0x13, 0x24, 0x63, 0xf5,
11+
0xe0, 0x3c, 0x48, 0x00, 0x22, 0x30, 0xf7, 0x80, 0xc2, 0x42, 0xe1, 0x7f, 0x3a, 0x25, 0xfc, 0x86, 0xf0, 0x7f, 0x41,
12+
0x33, 0x98, 0x2e, 0xc2, 0xc4, 0xd6, 0x6f, 0xf1, 0x30, 0xf1, 0x08, 0xc4, 0x6f, 0x11, 0x24, 0xff, 0x03, 0x12, 0x24,
13+
0x00, 0xfc, 0x61, 0x09, 0xa2, 0x08, 0x36, 0xbe, 0x2a, 0xb9, 0x13, 0x24, 0x38, 0x00, 0x64, 0xbb, 0xd1, 0xbe, 0x94,
14+
0x0a, 0x71, 0x08, 0xd5, 0x42, 0x21, 0xbd, 0x91, 0xbc, 0xd2, 0x42, 0xc1, 0x42, 0x00, 0xb2, 0xfe, 0x82, 0x05, 0x2f,
15+
0x50, 0x30, 0x21, 0x2e, 0x21, 0xf2, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0xf0, 0x6f, 0x02, 0x30, 0x02, 0x42, 0x20,
16+
0x26, 0xe0, 0x6f, 0x02, 0x31, 0x03, 0x40, 0x9a, 0x0a, 0x02, 0x42, 0xf0, 0x37, 0x05, 0x2e, 0x5e, 0xf7, 0x10, 0x08,
17+
0x12, 0x24, 0x1e, 0xf2, 0x80, 0x42, 0x83, 0x84, 0xf1, 0x7f, 0x0a, 0x25, 0x13, 0x30, 0x83, 0x42, 0x3b, 0x82, 0xf0,
18+
0x6f, 0x00, 0x2e, 0x00, 0x2e, 0xd0, 0x2e, 0x12, 0x40, 0x52, 0x42, 0x00, 0x2e, 0x12, 0x40, 0x52, 0x42, 0x3e, 0x84,
19+
0x00, 0x40, 0x40, 0x42, 0x7e, 0x82, 0xe1, 0x7f, 0xf2, 0x7f, 0x98, 0x2e, 0x6a, 0xd6, 0x21, 0x30, 0x23, 0x2e, 0x61,
20+
0xf5, 0xeb, 0x2c, 0xe1, 0x6f
21+
};

0 commit comments

Comments
 (0)