BNO085 I2C with STM32H7A3 via SH2 library — stuck at 44Hz but ESP32 achieves 1.2ms read time
Hi everyone,
I am working on a project using BNO085 IMU sensor and STM32H7A3ZIT6Q. I have a single sensor working but stuck at 44Hz. The same sensor with SparkFun library on ESP32 achieves 1.2ms read time. I need help understanding why and how to match ESP32 performance on STM32.
Hardware:
- NUCLEO-H7A3ZI-Q (STM32H7A3ZIT6Q, Cortex-M7 @ 280MHz)
- Adafruit BNO085 breakout board
- I2C on PB8 (SCL), PB9 (SDA), PC0 (INT pin)
- P0 and P1 tied to GND (I2C mode, address 0x4A)
Software:
- STM32CubeIDE with HAL
- Official CEVA SH2 library from github.com/ceva-dsp/sh2
- REPORT_INTERVAL_US = 2500 (targeting 400Hz)
- SH2_ROTATION_VECTOR (9-axis full quaternion)
STM32 performance achieved so far:
- I2C 400kHz polling: 28Hz, read_ms = 32ms
- I2C 1MHz Fast Mode Plus: 44Hz, read_ms = 19ms
- INT pin wait inside sh2_hal_read(): still 44Hz, read_ms = 19ms
ESP32 performance with same sensor and SparkFun SH2 library:
- read time: 1.2ms
- Data rate: close to 400Hz
This is a huge difference. 19ms on STM32 vs 1.2ms on ESP32 with the same SH2 library underneath.
Current STM32 sh2_hal_read implementation:
static int sh2_hal_read( sh2_Hal_t *self, uint8_t *pBuffer, unsigned len, uint32_t *t_us )
{
uint32_t timeout = HAL_GetTick() + 100;
while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) == GPIO_PIN_SET)
{
if (HAL_GetTick() > timeout) return 0;
}
HAL_StatusTypeDef status;
status = HAL_I2C_Master_Receive( &hi2c1, BNO085_ADDR, pBuffer, len, 100 );
if( status != HAL_OK ) return SH2_ERR_IO;
*t_us = HAL_GetTick() * 1000;
return len;
}Key observation: ESP32 SparkFun library reads 4 byte header first, then reads payload in 32 byte chunks with INT pin check between each chunk. Our STM32 reads entire packet in one HAL_I2C_Master_Receive call. Not sure if this is the cause of the difference.
What I have tried:
- I2C 400kHz to 1MHz Fast Mode Plus — improved from 28Hz to 44Hz
- INT pin wait inside sh2_hal_read() — no improvement
- Direct pin polling in main loop — no improvement
Questions:
- Why does ESP32 achieve 1.2ms at 400kHz I2C while STM32 takes 19ms at 1MHz?
- Is the bottleneck in HAL_I2C_Master_Receive vs ESP32 Wire implementation?
- Has anyone implemented a proper sh2_hal_read() for STM32H7 that achieves fast read times?
- Has anyone used I2C DMA with SH2 library on STM32H7? What improvement did you see?
- Is SPI the only reliable path to 200Hz+?
Edited to apply source code formatting - please see How to insert source code for future reference.
