/
fifo_watermark_headerless_mode.c
326 lines (247 loc) · 11.6 KB
/
fifo_watermark_headerless_mode.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/**\
* Copyright (c) 2023 Bosch Sensortec GmbH. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
**/
/******************************************************************************/
/*! Header Files */
#include <stdio.h>
#include "bmi270.h"
#include "common.h"
/******************************************************************************/
/*! Macros */
/*! Buffer size allocated to store raw FIFO data */
#define BMI2_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(800)
/*! Length of data to be read from FIFO */
#define BMI2_FIFO_RAW_DATA_USER_LENGTH UINT16_C(800)
/*! Number of accel frames to be extracted from FIFO */
/*!
* Calculation:
* fifo_watermark_level = 650, accel_frame_len = 6, gyro_frame_len = 6.
* fifo_accel_frame_count = (650 / (6 + 6 )) = 54 frames
*/
#define BMI2_FIFO_ACCEL_FRAME_COUNT UINT8_C(54)
/*! Number of gyro frames to be extracted from FIFO */
#define BMI2_FIFO_GYRO_FRAME_COUNT UINT8_C(54)
/*! Setting a watermark level in FIFO */
#define BMI2_FIFO_WATERMARK_LEVEL UINT16_C(650)
/******************************************************************************/
/*! Global Variables */
/* Number of bytes of FIFO data
* NOTE : Dummy byte (for SPI Interface) required for FIFO data read must be given as part of array size
*/
uint8_t fifo_data[BMI2_FIFO_RAW_DATA_BUFFER_SIZE] = { 0 };
/* Array of accelerometer frames -> Total bytes =
* 50 * (6 axes bytes) = 300 bytes */
struct bmi2_sens_axes_data fifo_accel_data[BMI2_FIFO_ACCEL_FRAME_COUNT] = { { 0 } };
/* Array of gyro frames -> Total bytes =
* 50 * (6 axes bytes) = 300 bytes */
struct bmi2_sens_axes_data fifo_gyro_data[BMI2_FIFO_GYRO_FRAME_COUNT] = { { 0 } };
/******************************************************************************/
/*! Static Function Declaration */
/*!
* @brief This internal API is used to set configurations for accel and gyro.
* @param[in] dev : Structure instance of bmi2_dev.
* @return Status of execution.
*/
static int8_t set_accel_gyro_config(struct bmi2_dev *dev);
/******************************************************************************/
/*! Functions */
/* This function starts the execution of program. */
int main(void)
{
/* Status of api are returned to this variable. */
int8_t rslt;
/* Variable to index bytes. */
uint16_t index = 0;
uint16_t fifo_length = 0;
uint16_t accel_frame_length;
uint16_t gyro_frame_length;
uint8_t try = 1;
/* Sensor initialization configuration. */
struct bmi2_dev bmi2_dev;
/* Initialize FIFO frame structure. */
struct bmi2_fifo_frame fifoframe = { 0 };
/* Accel and gyro sensor are listed in array. */
uint8_t sensor_sel[2] = { BMI2_ACCEL, BMI2_GYRO };
/* Variable to get fifo water-mark interrupt status. */
uint16_t int_status = 0;
uint16_t watermark = 0;
/* Interface reference is given as a parameter
* For I2C : BMI2_I2C_INTF
* For SPI : BMI2_SPI_INTF
*/
rslt = bmi2_interface_init(&bmi2_dev, BMI2_I2C_INTF);
bmi2_error_codes_print_result(rslt);
/* Initialize bmi270. */
rslt = bmi270_init(&bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Configuration settings for accel and gyro. */
rslt = set_accel_gyro_config(&bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* NOTE:
* Accel and Gyro enable must be done after setting configurations
*/
rslt = bmi270_sensor_enable(sensor_sel, 2, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Before setting FIFO, disable the advance power save mode. */
rslt = bmi2_set_adv_power_save(BMI2_DISABLE, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Initially disable all configurations in fifo. */
rslt = bmi2_set_fifo_config(BMI2_FIFO_ALL_EN, BMI2_DISABLE, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Update FIFO structure. */
/* Mapping the buffer to store the fifo data. */
fifoframe.data = fifo_data;
/* Length of FIFO frame. */
fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH;
/* Set FIFO configuration by enabling accel, gyro.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bmi2_set_fifo_config(BMI2_FIFO_ACC_EN | BMI2_FIFO_GYR_EN, BMI2_ENABLE, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
printf("FIFO is configured in headerless mode\n");
/* To enable headerless mode, disable the header. */
if (rslt == BMI2_OK)
{
rslt = bmi2_set_fifo_config(BMI2_FIFO_HEADER_EN, BMI2_DISABLE, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
}
/* FIFO water-mark interrupt is enabled. */
fifoframe.data_int_map = BMI2_FWM_INT;
/* Map water-mark interrupt to the required interrupt pin. */
rslt = bmi2_map_data_int(fifoframe.data_int_map, BMI2_INT1, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Set water-mark level. */
fifoframe.wm_lvl = BMI2_FIFO_WATERMARK_LEVEL;
fifoframe.length = BMI2_FIFO_RAW_DATA_USER_LENGTH;
/* Set the water-mark level if water-mark interrupt is mapped. */
rslt = bmi2_set_fifo_wm(fifoframe.wm_lvl, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
while (try <= 10)
{
/* Read FIFO data on interrupt. */
rslt = bmi2_get_int_status(&int_status, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* To check the status of FIFO watermark interrupt. */
if ((rslt == BMI2_OK) && (int_status & BMI2_FWM_INT_STATUS_MASK))
{
printf("\nIteration : %d\n", try);
rslt = bmi2_get_fifo_wm(&watermark, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
printf("\nFIFO watermark level : %d\n", watermark);
rslt = bmi2_get_fifo_length(&fifo_length, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
accel_frame_length = BMI2_FIFO_ACCEL_FRAME_COUNT;
gyro_frame_length = BMI2_FIFO_GYRO_FRAME_COUNT;
/* Updating FIFO length to be read based on available length and dummy byte updation */
fifoframe.length = fifo_length + bmi2_dev.dummy_byte;
printf("\nFIFO data bytes available : %d \n", fifo_length);
printf("\nFIFO data bytes requested : %d \n", fifoframe.length);
/* Read FIFO data. */
rslt = bmi2_read_fifo_data(&fifoframe, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
/* Read FIFO data on interrupt. */
rslt = bmi2_get_int_status(&int_status, &bmi2_dev);
bmi2_error_codes_print_result(rslt);
if (rslt == BMI2_OK)
{
printf("\nFIFO accel frames requested : %d \n", accel_frame_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer. */
(void)bmi2_extract_accel(fifo_accel_data, &accel_frame_length, &fifoframe, &bmi2_dev);
printf("\nFIFO accel frames extracted : %d \n", accel_frame_length);
printf("\nFIFO gyro frames requested : %d \n", gyro_frame_length);
/* Parse the FIFO data to extract gyro data from the FIFO buffer. */
(void)bmi2_extract_gyro(fifo_gyro_data, &gyro_frame_length, &fifoframe, &bmi2_dev);
printf("\nFIFO gyro frames extracted : %d \n", gyro_frame_length);
printf("\nExtracted accel frames\n");
printf("ACCEL_DATA, X, Y, Z\n");
/* Print the parsed accelerometer data from the FIFO buffer. */
for (index = 0; index < accel_frame_length; index++)
{
printf("%d, %d, %d, %d\n",
index,
fifo_accel_data[index].x,
fifo_accel_data[index].y,
fifo_accel_data[index].z);
}
printf("\nExtracted gyro frames\n");
printf("GYRO_DATA, X, Y, Z\n");
/* Print the parsed gyro data from the FIFO buffer. */
for (index = 0; index < gyro_frame_length; index++)
{
printf("%d, %d, %d, %d\n", index, fifo_gyro_data[index].x, fifo_gyro_data[index].y,
fifo_gyro_data[index].z);
}
}
try++;
}
}
bmi2_coines_deinit();
return rslt;
}
/*!
* @brief This internal API is used to set configurations for accel.
*/
static int8_t set_accel_gyro_config(struct bmi2_dev *dev)
{
/* Status of api are returned to this variable. */
int8_t rslt;
/* Structure to define accel and gyro configurations. */
struct bmi2_sens_config config[2];
/* Configure the type of feature. */
config[0].type = BMI2_ACCEL;
config[1].type = BMI2_GYRO;
/* Get default configurations for the type of feature selected. */
rslt = bmi270_get_sensor_config(config, 2, dev);
bmi2_error_codes_print_result(rslt);
if (rslt == BMI2_OK)
{
/* NOTE: The user can change the following configuration parameter according to their requirement. */
/* Accel configuration settings. */
/* Set Output Data Rate */
config[0].cfg.acc.odr = BMI2_ACC_ODR_100HZ;
/* Gravity range of the sensor (+/- 2G, 4G, 8G, 16G). */
config[0].cfg.acc.range = BMI2_ACC_RANGE_2G;
/* The bandwidth parameter is used to configure the number of sensor samples that are averaged
* if it is set to 2, then 2^(bandwidth parameter) samples
* are averaged, resulting in 4 averaged samples
* Note1 : For more information, refer the datasheet.
* Note2 : A higher number of averaged samples will result in a lower noise level of the signal, but
* this has an adverse effect on the power consumed.
*/
config[0].cfg.acc.bwp = BMI2_ACC_NORMAL_AVG4;
/* Enable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Ultra low power mode
* 1 -> High performance mode(Default)
* For more info refer datasheet.
*/
config[0].cfg.acc.filter_perf = BMI2_PERF_OPT_MODE;
/* Gyro configuration settings. */
/* Set Output Data Rate */
config[1].cfg.gyr.odr = BMI2_GYR_ODR_100HZ;
/* Gyroscope Angular Rate Measurement Range.By default the range is 2000dps. */
config[1].cfg.gyr.range = BMI2_GYR_RANGE_2000;
/* Gyroscope Bandwidth parameters. By default the gyro bandwidth is in normal mode. */
config[1].cfg.gyr.bwp = BMI2_GYR_NORMAL_MODE;
/* Enable/Disable the noise performance mode for precision yaw rate sensing
* There are two modes
* 0 -> Ultra low power mode(Default)
* 1 -> High performance mode
*/
config[1].cfg.gyr.noise_perf = BMI2_POWER_OPT_MODE;
/* Enable/Disable the filter performance mode where averaging of samples
* will be done based on above set bandwidth and ODR.
* There are two modes
* 0 -> Ultra low power mode
* 1 -> High performance mode(Default)
*/
config[1].cfg.gyr.filter_perf = BMI2_PERF_OPT_MODE;
/* Set new configurations. */
rslt = bmi270_set_sensor_config(config, 2, dev);
bmi2_error_codes_print_result(rslt);
}
return rslt;
}