09-24-2021 03:16 PM
Hello there,
I am currently trying to read out the BMA456 accelerometer data using FIFO.
It works great until I enable BMA456 features. After I write the configuration file into BMA456 (even without features settings), the FIFO is never supposed to work then, although while debugging it can be seen that the configurations of FIFO are OK.
Can anyone please help me?
Regards,
Roman.
09-24-2021 04:30 PM
Hello keizerr,
What is the driver code you used?
Could we know what is the specific description of FIFO not working?
09-24-2021 05:07 PM
Hello,
Thanks for your response.
The complete source code is just this:
#include "main.hpp"
#include <stdio.h>
#include "bma456h.h"
#include "bma4_common.h"
#include "retarget.h"
#include "bma4.h"
/******************************************************************************/
/*! Macro definition */
/*! Buffer size allocated to store raw FIFO data */
#define BMA456H_FIFO_RAW_DATA_BUFFER_SIZE UINT16_C(1024)
/*! Length of data to be read from FIFO */
#define BMA456H_FIFO_RAW_DATA_USER_LENGTH UINT16_C(1024)
/*! Setting a watermark level in FIFO */
#define BMA456H_FIFO_WATERMARK_LEVEL UINT16_C(192)
/*! Number of accel frames to be extracted from FIFO
* Calculation:
* fifo_watermark_level = 600, accel_frame_len = 6.
* fifo_accel_frame_count = (600 / 6) = 100 frames
*/
#define BMA456H_FIFO_ACCEL_FRAME_COUNT UINT8_C(32)
struct bma4_int_pin_config bmint = {0};
/******************************************************************************/
/*! Function */
/* This function starts the execution of program */
int main(void) {
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_I2C1_Init();
RetargetInit(&huart2);
printf("Start! \n\r");
uint8_t anymot_en[2] = {0x28, 0x3F};
/* Status of API are returned to this variable */
int8_t rslt;
/* Accelerometer configuration structure */
struct bma4_accel_config acc_conf = {0};
struct bma456h_any_no_mot_config any_mot = {0};
struct bma456h_auto_low_power balp = {0};
/* Sensor initialization configuration */
struct bma4_dev dev = {0};
/* Number of accelerometer frames */
uint16_t accel_length;
/* Variable to idx bytes */
uint16_t idx = 0;
/* Variable to store the available frame length count in FIFO */
uint8_t frame_count;
/* Number of bytes of FIFO data */
uint8_t fifo_data[BMA456H_FIFO_RAW_DATA_BUFFER_SIZE] = {0};
/* Array of accelerometer frames -> Total bytes =
* 100 * (6 axes bytes(+/- x,y,z)) = 600 bytes */
struct bma4_accel fifo_accel_data[BMA456H_FIFO_ACCEL_FRAME_COUNT] = {0};
/* Initialize FIFO frame structure */
struct bma4_fifo_frame fifoframe = {0};
/* Variable that contains interrupt status value */
uint8_t int_status = 0;
/* Variable to hold the length of FIFO data */
uint16_t fifo_length = 0;
uint16_t watermark = 0;
/* To set the watermark level in FIFO */
uint16_t wm_lvl;
/* Function to select interface between SPI and I2C, according to that the device structure gets updated */
rslt = bma4_interface_selection(&dev);
bma4_error_codes_print_result("bma4_interface_selection status", rslt);
bma4_soft_reset(&dev);
HAL_Delay(500);
/* Initialize BMA456H */
rslt = bma456h_init(&dev);
bma4_error_codes_print_result("bma456h_init status", rslt);
rslt = bma456h_write_config_file(&dev);
/* Enable the accelerometer sensor */
rslt = bma4_set_accel_enable(BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_accel_enable status", rslt);
/* Accelerometer configuration settings */
acc_conf.odr = BMA4_OUTPUT_DATA_RATE_100HZ;
acc_conf.bandwidth = BMA4_ACCEL_NORMAL_AVG4;
acc_conf.range = BMA4_ACCEL_RANGE_2G;
/* Set the accel configurations */
rslt = bma4_set_accel_config(&acc_conf, &dev);
bma4_error_codes_print_result("bma4_set_accel_config status", rslt);
/* Disabling advance power save mode as FIFO data is not accessible in advance low power mode */
rslt = bma4_set_advance_power_save(BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_advance_power_save status", rslt);
/* Clear FIFO configuration register */
rslt = bma4_set_fifo_config(BMA4_FIFO_ALL, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config disable status", rslt);
/* Set FIFO configuration by enabling accel.
* NOTE 1: The header mode is enabled by default.
* NOTE 2: By default the FIFO operating mode is FIFO mode. */
rslt = bma4_set_fifo_config(BMA4_FIFO_ACCEL, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config enable status", rslt);
/* Update FIFO structure */
fifoframe.data = fifo_data;
fifoframe.length = BMA456H_FIFO_RAW_DATA_USER_LENGTH;
/* To enable headerless mode, disable the header. */
rslt = bma4_set_fifo_config(BMA4_FIFO_HEADER, BMA4_DISABLE, &dev);
bma4_error_codes_print_result("bma4_set_fifo_config status", rslt);
printf("FIFO is configured in headerless mode\n");
HAL_I2C_Master_Transmit(&hi2c1, BMA4_I2C_ADDR_PRIMARY << 1, anymot_en, 2, HAL_MAX_DELAY);
rslt = bma456h_get_any_mot_config(&any_mot, &dev);
if (rslt == BMA4_OK) {
any_mot.threshold = 129;
any_mot.duration = 16;
any_mot.intr_bhvr = 0;
any_mot.slope = 1;
rslt = bma456h_set_any_mot_config(&any_mot, &dev);
}
rslt = bma4_get_int_pin_config(&bmint, 0, &dev);
if (rslt == BMA4_OK) {
bmint.edge_ctrl = 0;
bmint.input_en = 0;
bmint.lvl = 1;
bmint.od = 0;
bmint.output_en = 1;
rslt = bma4_set_int_pin_config(&bmint, 0, &dev);
}
rslt = bma4_get_int_pin_config(&bmint, 1, &dev);
if (rslt == BMA4_OK) {
bmint.edge_ctrl = 0;
bmint.input_en = 0;
bmint.lvl = 1;
bmint.od = 0;
bmint.output_en = 1;
rslt = bma4_set_int_pin_config(&bmint, 1, &dev);
}
bma4_set_interrupt_mode(BMA4_LATCH_MODE, &dev);
rslt = bma456h_map_interrupt(BMA4_INTR1_MAP, BMA456H_ANY_MOT_INT, BMA4_ENABLE, &dev);
rslt = bma456h_map_interrupt(BMA4_INTR2_MAP, BMA4_FIFO_WM_INT, BMA4_ENABLE, &dev);
bma4_error_codes_print_result("bma456h_map_interrupt status", rslt);
wm_lvl = BMA456H_FIFO_WATERMARK_LEVEL;
rslt = bma4_set_fifo_wm(wm_lvl, &dev);
bma4_error_codes_print_result("bma4_set_fifo_wm status", rslt);
rslt = bma4_get_fifo_wm(&watermark, &dev);
bma4_error_codes_print_result("bma4_get_fifo_wm status", rslt);
rslt = bma456h_feature_enable(BMA456H_AUTO_LOW_POWER_EN, BMA4_ENABLE, &dev);
rslt = bma456h_get_auto_low_power_config(&balp, &dev);
if (rslt == BMA4_OK) {
balp.lp_odr = 3;
balp.no_motion = 0;
balp.time_out = 1;
balp.time_out_dur = 150;
balp.pwr_mgt = 1;
rslt = bma456h_set_auto_low_power_config(&balp, &dev);
}
printf("FIFO watermark level is %d\n", watermark);
while (1) {
rslt = bma4_read_int_status_1(int_status, &dev);
bma4_error_codes_print_result("bma456h_read_int_status", rslt);
if ((rslt == BMA4_OK) && (int_status & 0x02)) {
rslt = bma4_get_fifo_length(&fifo_length, &dev);
bma4_error_codes_print_result("bma4_get_fifo_length status", rslt);
printf("FIFO data bytes available : %d\n", fifo_length);
printf("FIFO data bytes requested : %d\n", fifoframe.length);
/* Read FIFO data */
rslt = bma4_read_fifo_data(&fifoframe, &dev);
bma4_error_codes_print_result("bma4_read_fifo_data status", rslt);
accel_length = BMA456H_FIFO_ACCEL_FRAME_COUNT;
if (rslt == BMA4_OK) {
printf("Requested data frames before parsing: %d\n", accel_length);
/* Parse the FIFO data to extract accelerometer data from the FIFO buffer */
rslt = bma4_extract_accel(fifo_accel_data, &accel_length, &fifoframe, &dev);
printf("Parsed accelerometer data frames: %d\n", accel_length);
/* Calculating the frame count from the available bytes in FIFO
* frame_length = (available_fifo_bytes / acc_frame_len) */
frame_count = (fifo_length / BMA4_FIFO_A_LENGTH);
printf("Available frame count: %d\n", frame_count);
/* Print the parsed accelerometer data from the FIFO buffer */
for (idx = 0; idx < frame_count; idx++) {
printf("ACCEL[%d] X : %d Y : %d Z : %d\n",
idx,
fifo_accel_data[idx].x,
fifo_accel_data[idx].y,
fifo_accel_data[idx].z);
}
}
// break;
}
}
return rslt;
}
"FIFO not working" in this case means, that when this line is commented out:
rslt = bma456h_write_config_file(&dev);
I am able to see the FIFO data via logic analyzer or PuTTY. Watermark interrupts are being correctly asserted.
But when I write the config file, no data can be seen via mentioned tools.
So I cannot use FIFO when using application necessary BMA456 features like any motion or auto low power.
Thanks,
Roman.
09-26-2021 03:37 AM
Hello keizerr,
Could we know what is your application first as you used bma456h_xxx driver code?
There are bma456.c(.h) and bma456h.c(.h) BMA456 driver code in github. bma456.c(.h) focus on wearable and general applicatoin, bma456h.c(.h) focus on hearable application.
09-27-2021 08:51 AM
Hello BSTRobin,
Sorry, but...seriously?
I have already explained the concepts of my application as thoroughly as my company's rules let me do that. Here:
https://community.bosch-sensortec.com/t5/MEMS-sensors-forum/Possible-bug-in-BMA456-driver/m-p/46299#...