03-27-2022 08:32 PM
Hi,
So I am trying to get my bhi160b to work and stream accelerometer data connected to a stm32f7 via i2c.
Here I have used some of the example code:
Together with the following firmware: Bosch_PCB_7183_di03_BMI160-7183_di03.2.1.11696_170103.h
void demo_sensor(void)
{
int8_t ret;
/* BHY Variable*/
uint8_t *fifoptr = NULL;
uint8_t bytes_left_in_fifo = 0;
uint16_t bytes_remaining = 0;
uint16_t bytes_read = 0;
bhy_data_generic_t fifo_packet;
bhy_data_type_t packet_type;
BHY_RETURN_FUNCTION_TYPE result;
/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
/* to get this information. This feature is only supported for customized firmware. To get this customized */
/* firmware, you need to contact your local FAE of Bosch Sensortec. */
//struct cus_version_t bhy_cus_version;
BHY_RETURN_FUNCTION_TYPE com_rslt = BHY_COMM_RES;
uint8_t data[1] = {1};
com_rslt = bhy_write_reg(BHY_I2C_REG_RESET_REQUEST_ADDR, data, sizeof(data));
while (!bhi160b_get_int_status());
osDelay(5000);
// bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_ERROR, meta_event_callback);
// bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_SENSOR_ERROR, meta_event_callback);
bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_INITIALIZED, meta_event_callback);
bhy_install_meta_event_callback(BHY_META_EVENT_TYPE_SELF_TEST_RESULTS, meta_event_callback);
bhy_install_sensor_callback(VS_ID_CUS1, VS_WAKEUP, sensors_callback);
// PDEBUG("version=%s, %s, %s\n", bhy_get_version(), __DATE__, __TIME__);
// PDEBUG("start example\n");
/* init the bhy chip */
if(bhy_driver_init(bhy1_fw))
{
PDEBUG("Fail to init bhy\n");
}
/* wait for the bhy trigger the interrupt pin go down and up again */
while(bhi160b_get_int_status());
while(!bhi160b_get_int_status());
/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
/* to get this information. This feature is only supported for customized firmware. To get this customized */
/* firmware, you need to contact your local FAE of Bosch Sensortec. */
//bhy_read_parameter_page(BHY_PAGE_2, PAGE2_CUS_FIRMWARE_VERSION, (uint8_t*)&bhy_cus_version, sizeof(struct cus_version_t));
//PDEBUG("cus version base:%d major:%d minor:%d\n", bhy_cus_version.base, bhy_cus_version.major, bhy_cus_version.minor);
struct accel_physical_status_t phy_acc;
struct gyro_physical_status_t phy_gyro;
struct mag_physical_status_t phy_mag;
uint8_t physical_sensor_present_bitmap[8];
uint32_t i = 0;
struct sensor_information_non_wakeup_t sensor_info_non_wakeup;
struct sensor_information_wakeup_t sensor_info_wakeup;
/* get physical sensor present from sensor hub */
bhy_read_parameter_page(BHY_PAGE_1, BHY_PARAM_SYSTEM_PHYSICAL_SENSOR_PRESENT, &physical_sensor_present_bitmap[0], 8);
PDEBUG("Physical Sensor Present:\n");
for(i = 0; i < 8; i++)
{
PDEBUG("bitmap[%d] = 0x%x\n", i, physical_sensor_present_bitmap[i]);
PDEBUG("");
}
/* get physical sensor status from sensor hub */
bhy_get_physical_sensor_status(&phy_acc, &phy_gyro, &phy_mag);
/* Physical Sensor Status:
Flags[bit 0]: interrupt enable
Flags[bits 5-7]: Sensor Power Mode values:
0: Sensor Not Present
1: Power Down
2: Suspend
3: Self-Test
4: Interrupt Motion
5: One Shot
6: Low Power Active
7: Active
*/
PDEBUG("Physical Sensor Status:\n");
PDEBUG("Acc : sample rate %d, range %d, int %d pwr %d\n",\
phy_acc.accel_sample_rate, phy_acc.accel_dynamic_range, phy_acc.accel_flag & 0x01, (phy_acc.accel_flag & 0xE0) >> 5);
PDEBUG("Gyro: sample rate %d, range %d, int %d pwr %d\n", \
phy_gyro.gyro_sample_rate, phy_gyro.gyro_dynamic_range, phy_gyro.gyro_flag & 0x01, (phy_gyro.gyro_flag & 0xE0) >> 5);
PDEBUG("Mag : sample rate %d, range %d, int %d pwr %d\n", \
phy_mag.mag_sample_rate, phy_mag.mag_dynamic_range, phy_mag.mag_flag & 0x01, (phy_mag.mag_flag & 0xE0) >> 5);
PDEBUG("");
/* read custom sensor event size from hub for later fifo parse */
bhy_sync_cus_evt_size();
PDEBUG("cus evt size = %d %d %d %d %d\n", bhy_get_cus_evt_size(VS_ID_CUS1), bhy_get_cus_evt_size(VS_ID_CUS2), \
bhy_get_cus_evt_size(VS_ID_CUS3), bhy_get_cus_evt_size(VS_ID_CUS4), \
bhy_get_cus_evt_size(VS_ID_CUS5));
/* get virtual sensor information from sensor hub */
PDEBUG("Supported Virtual Sensor Information:\n");
for(i = 1; i < 32; i++)
{
bhy_get_wakeup_sensor_information(i, &sensor_info_wakeup);
if(sensor_info_wakeup.wakeup_sensor_type == i)
PDEBUG("id=%2d\n", i);
}
for(i = 33; i < 64; i++)
{
bhy_get_non_wakeup_sensor_information(i, &sensor_info_non_wakeup);
if(sensor_info_non_wakeup.non_wakeup_sensor_type == i)
PDEBUG("id=%2d\n", i);
}
PDEBUG("");
bool shouldSelftest = false;
if (shouldSelftest) {
bhy_set_chip_control(0);
bhy_set_host_interface_control(BHY_HOST_SELFTEST, ENABLE);
osDelay(100);
bhy_set_chip_control(1);
osDelay(100);
} else {
bhy_enable_virtual_sensor(VS_ID_CUS1, VS_WAKEUP, 5, 0, VS_FLUSH_NONE, 0, 0);
}
while(1)
{
osDelay(1);
/* wait until the interrupt fires */
/* unless we already know there are bytes remaining in the fifo */
while (!bhi160b_get_int_status() && !bytes_remaining);
bhy_read_fifo(fifo + bytes_left_in_fifo, FIFO_SIZE - bytes_left_in_fifo, &bytes_read, &bytes_remaining);
bytes_read += bytes_left_in_fifo;
fifoptr = fifo;
packet_type = BHY_DATA_TYPE_PADDING;
do
{
/* this function will call callbacks that are registered */
result = bhy_parse_next_fifo_packet(&fifoptr, &bytes_read, &fifo_packet, &packet_type);
/* prints all the debug packets */
if (packet_type == BHY_DATA_TYPE_PADDING)
{
/* padding data only added at the end of each FIFO dump, discard it. */
PDEBUG(">Padding\n");
}
else if (packet_type == BHY_DATA_TYPE_DEBUG)
{
PDEBUG(">DebugString :");
bhy_print_debug_packet(&fifo_packet.data_debug, bhy_printf);
PDEBUG("\n");
}
/* the logic here is that if doing a partial parsing of the fifo, then we should not parse */
/* the last 18 bytes (max length of a packet) so that we don't try to parse an incomplete */
/* packet */
} while ((result == BHY_SUCCESS) && (bytes_read > (bytes_remaining ? MAX_PACKET_LENGTH : 0)));
bytes_left_in_fifo = 0;
if (bytes_remaining)
{
/* shifts the remaining bytes to the beginning of the buffer */
while (bytes_left_in_fifo < bytes_read)
{
fifo[bytes_left_in_fifo++] = *(fifoptr++);
}
}
}
}
Callback:
static void meta_event_callback(bhy_data_meta_event_t *event_data, bhy_meta_event_type_t event_type)
{
PDEBUG(">Meta event type %d, \n", event_type);
switch(event_type)
{
case BHY_META_EVENT_TYPE_INITIALIZED:
PDEBUG("initialize success!\n");
break;
case BHY_META_EVENT_TYPE_SELF_TEST_RESULTS:
if(event_data->event_specific == BHY_SUCCESS)
{
PDEBUG("self test result success! sensor_type=%d \n", event_data->sensor_type);
}
else
{
PDEBUG("self test result fail! sensor_type=%d \n", event_data->sensor_type);
}
break;
case BHY_META_EVENT_TYPE_ERROR:
{
PDEBUG("error meta event\n");
}
break;
default:
PDEBUG("unknown meta event\n");
break;
}
}
However this causes BHY_META_EVENT_TYPE_ERROR once entering the meta_callback after first time processing fifo.
There are no more events following that event. neither sensor or meta callback.
And the code snippet bellow shows that the flags for phy_acc is 0x20. which means suspended mode, is there any way to take it out of suspended?
/* get physical sensor status from sensor hub */
bhy_get_physical_sensor_status(&phy_acc, &phy_gyro, &phy_mag);
Attached my hw schematics.
03-28-2022 09:17 AM
Hi robinpipers,
Run the same code, I got the following result, haven't found 0x20 acc flag.
What is the full running result of your program?
03-28-2022 07:28 PM - edited 03-28-2022 07:29 PM
Wait... I get the same as you.
I have only debuged it previously and missed the mask when reading flags. If logging I get the same result.
If I also uncomment the lines for meta callback etc. I get the following.
Then after running for 5s the error callback is triggered.
Then my next question is how do i get to set sample rate and actually get the accelerometer to produce samples.
03-29-2022 08:28 AM
Hi robinpipers,
You could refer the following code to read acc data with 100 Hz.
static void sensors_callback_acc(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id)
{
switch(sensor_id)
{
case VS_ID_ACCELEROMETER:
case VS_ID_ACCELEROMETER_WAKEUP:
PDEBUG("acc,%d,%d,%d\r\n", sensor_data->data_vector.x, sensor_data->data_vector.y, sensor_data->data_vector.z);
break;
default:
PDEBUG("unknown id = %d\r\n", sensor_id);
break;
}
}
/* install the callback function for parse fifo data */
if(bhy_install_sensor_callback(VS_TYPE_ACCELEROMETER, VS_WAKEUP, sensors_callback_acc))
{
PDEBUG("Fail to install sensor callback\r\n");
}
/* enables the virtual sensor */
if(bhy_enable_virtual_sensor(VS_TYPE_ACCELEROMETER, VS_WAKEUP, 100, 0, VS_FLUSH_NONE, 0, 0))
{
PDEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ACCELEROMETER);
}
03-29-2022 09:52 PM
Thanks BSTRobin
I tried the following, but with no success.
No rtt prints.
static void sensors_callback_acc(bhy_data_generic_t * sensor_data, bhy_virtual_sensor_t sensor_id)
{
uint16_t i = 0;
switch(sensor_id)
{
case VS_ID_ACCELEROMETER:
case VS_ID_ACCELEROMETER_WAKEUP:
PDEBUG("acc,%d,%d,%d\r\n", sensor_data->data_vector.x, sensor_data->data_vector.y, sensor_data->data_vector.z);
break;
default:
PDEBUG("unknown id = %d\n", sensor_id);
break;
}
}
void demo_sensor(void)
{
int8_t ret;
/* BHY Variable*/
uint8_t *fifoptr = NULL;
uint8_t bytes_left_in_fifo = 0;
uint16_t bytes_remaining = 0;
uint16_t bytes_read = 0;
bhy_data_generic_t fifo_packet;
bhy_data_type_t packet_type;
BHY_RETURN_FUNCTION_TYPE result;
/* To get the customized version number in firmware, it is necessary to read Parameter Page 2, index 125 */
/* to get this information. This feature is only supported for customized firmware. To get this customized */
/* firmware, you need to contact your local FAE of Bosch Sensortec. */
//struct cus_version_t bhy_cus_version;
// BHY_RETURN_FUNCTION_TYPE com_rslt = BHY_COMM_RES;
// uint8_t data[1] = {1};
// com_rslt = bhy_write_reg(BHY_I2C_REG_RESET_REQUEST_ADDR, data, sizeof(data));
// while (!bhi160b_get_int_status());
// osDelay(100);
/* init the bhy chip */
if(bhy_driver_init(bhy1_fw))
{
PDEBUG("Fail to init bhy\n");
}
/* wait for the bhy trigger the interrupt pin go down and up again */
while(bhi160b_get_int_status());
while(!bhi160b_get_int_status());
/* install the callback function for parse fifo data */
if(bhy_install_sensor_callback(VS_TYPE_ACCELEROMETER, VS_WAKEUP, sensors_callback_acc)) {
PDEBUG("Fail to install sensor callback\r\n");
}
if(bhy_enable_virtual_sensor(VS_TYPE_ACCELEROMETER, VS_WAKEUP, 100, 0, VS_FLUSH_NONE, 0, 0)) {
PDEBUG("Fail to enable sensor id=%d\n", VS_TYPE_ACCELEROMETER);
}
while(1)
{
osDelay(1);
/* wait until the interrupt fires */
/* unless we already know there are bytes remaining in the fifo */
while (!bhi160b_get_int_status() && !bytes_remaining);
bhy_read_fifo(fifo + bytes_left_in_fifo, FIFO_SIZE - bytes_left_in_fifo, &bytes_read, &bytes_remaining);
bytes_read += bytes_left_in_fifo;
fifoptr = fifo;
packet_type = BHY_DATA_TYPE_PADDING;
do
{
/* this function will call callbacks that are registered */
result = bhy_parse_next_fifo_packet(&fifoptr, &bytes_read, &fifo_packet, &packet_type);
/* prints all the debug packets */
if (packet_type == BHY_DATA_TYPE_PADDING)
{
/* padding data only added at the end of each FIFO dump, discard it. */
PDEBUG(">Padding\n");
}
else if (packet_type == BHY_DATA_TYPE_DEBUG)
{
PDEBUG(">DebugString :");
bhy_print_debug_packet(&fifo_packet.data_debug, bhy_printf);
PDEBUG("\n");
}
/* the logic here is that if doing a partial parsing of the fifo, then we should not parse */
/* the last 18 bytes (max length of a packet) so that we don't try to parse an incomplete */
/* packet */
} while ((result == BHY_SUCCESS) && (bytes_read > (bytes_remaining ? MAX_PACKET_LENGTH : 0)));
bytes_left_in_fifo = 0;
if (bytes_remaining)
{
/* shifts the remaining bytes to the beginning of the buffer */
while (bytes_left_in_fifo < bytes_read)
{
fifo[bytes_left_in_fifo++] = *(fifoptr++);
}
}
}
}