10-10-2019 01:39 PM
Hello,
I am trying to get a BHI160 working with a STM32 microcontroller. My code is based on the sample code in the GitHub repository. I have attached my code at the bottom of this post.
Communicating with the chip seems to work fine. bhy_driver_init() returns 0. However, the INT pin never changes, so my code is stuck in the loops that wait for an edge on INT. If I remove the loops and start reading FIFO data right away, no data is received. I expect an initialization meta message and the sensor data from the accelerometer, but data_read is always 0.
int ret;
uint8_t fifo[100];
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;
if(bhy_driver_init(bhy1_fw)) {
return EB_ERROR;
}
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_SET) ;
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_RESET) ;
ret = bhy_enable_virtual_sensor(VS_TYPE_ACCELEROMETER, VS_WAKEUP, 10, 0, VS_FLUSH_NONE, 0, 0);
while(1) {
ret = bhy_read_fifo(fifo + bytes_left_in_fifo, 100 - 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 */
ret = bhy_parse_next_fifo_packet(&fifoptr, &bytes_read, &fifo_packet, &packet_type);
/* 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 ((ret == BHY_SUCCESS) && (bytes_read > (bytes_remaining ? 18 : 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++);
}
}
}
10-10-2019 02:37 PM - edited 10-10-2019 02:38 PM
When the BHI bootloader is ready to receive code, the INT pin goes high, so you should add the following before the bhy_driver_init:
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_RESET) ;
After the CPU run request (at the end of the init function) the INT pin goes low, then back high with the first interrupt. On a slow microcontroller, it is possibly that the INT pin is already low before you reach this line:
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_SET) ;
In which case, I recommend to switch to a delay instead, before waiting for the INT pin to go back high.
**Note: On BHI160 there is a bug in the ROM which causes a crash when if the hardware configuration does not match the firmware (e.g. if expecting a magnetometer that is not present or broken). In that case, there will be no interrupt. So to be safe, always use the Bosch_PCB_7183_di03_BMI160-7183 firmware for initial testing on BHI160B and Bosch_PCB_7183_di01_BMI160-7183 on BHI160.
10-10-2019 03:52 PM - edited 10-10-2019 04:02 PM
I now have this code:
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_RESET) ;
if(bhy_driver_init(bhy1_fw)) {
return EB_ERROR;
}
DelayMs(100);
while(HAL_GPIO_ReadPin(INT_BHI_GPIO_Port, INT_BHI_Pin) == GPIO_PIN_RESET) ;
The first loop finishes and bhy_driver_init() returns 0. But then the second loop runs forever, indicating I never receive anything in the FIFO, not even a message that initialization has finished.
10-11-2019 10:54 AM
10-11-2019 12:44 PM
1: I am using a custom board, the interface between the BHI160 and the microcontroller (STM32) is based on the schematic in the datasheet.
2: The number on the IC is 020 QP, I use BHI160, not the B version.
3: I use the firmware that is in the file "Bosch_PCB_7183_di01_BMI160-7183_di01.2.1.10836_170103.h" from the GitHub repository. Flashing the firmware seems to work, and the CRC checks work fine.
4: I did not convert the firmware myself, because I use the .h file from GitHub.
I attached a signal capture during the init process. The blue trace is SDA between STM32 and BHI160, the yellow trace is INT. I wait 1 second before starting the init process. As you can see, INT goes low for a short time, and then goes back to high. But that is still during the transfer of the firmware. After the transfer is complete, INT stays low.