Skip to content

Hardware

What to connect between your MCU and a BNO08x, with which bus settings, and the board-level traps to avoid.

All values here come from the BNO08X datasheet (CEVA 1000-3927, revision 1.17). Pin numbers are the 28-pin LGA's; a breakout board names them on its silkscreen and often straps some of them. When the datasheet and a board's schematic disagree, the schematic wins for what is strapped.

Host interface pins

Signal Pin Direction (chip) I2C SPI UART / UART-RVC
H_SCL / SCK / RX 19 in / bidirectional SCL SCK RX (host to chip)
H_SDA / H_MISO / TX 20 bidirectional / out SDA MISO TX (chip to host)
SA0 / H_MOSI 17 in Address bit 0 MOSI n/a
H_CSN 18 in n/a Chip select, active low n/a
H_INTN 14 out Data ready, active low Data ready, active low Asserted about 7.7 µs before each UART message (UART-SHTP)

Control pins

The driver addresses these by name (bno08x::CtrlPin) and by state (GpioSignal::ACTIVE / INACTIVE); your port maps a state to a level. ACTIVE means "function asserted", which is a low level on the three active-low pins.

Pin CtrlPin Direction (chip) What it does Driver use
NRST (11) RSTN in Active-low reset HardwareReset(), EnterBootloader(), ExitBootloaderAndReboot()
BOOTN (4) BOOTN in Low at reset: start the bootloader. Pull up through 10 kΩ SetBootPin(), the bootloader helpers
PS0 / WAKE (6) PS0, WAKE in Protocol select bit 0 at reset; in SPI mode, an active-low wake afterwards SelectInterface(), SetWakePin()
PS1 (5) PS1 in Protocol select bit 1 at reset SelectInterface()

Protocol selection

PS1, PS0 and BOOTN are sampled at reset (datasheet figure 1-5). Strap them, or drive them before you release NRST.

PS1 PS0 Application (BOOTN = 1) Bootloader (BOOTN = 0) BNO085Interface
0 0 I2C I2C I2C
0 1 UART-RVC Reserved UARTRVC
1 0 UART (SHTP) UART UART
1 1 SPI SPI SPI

If your board wires PS0 and PS1 to GPIOs, SelectInterface(iface) drives them to the row of the table for iface (the enum value is the PS1:PS0 pair); call it before HardwareReset().

Bus settings

Setting Value
Speed 100 kHz (standard) or 400 kHz (fast)
Address (7-bit) 0x4A (SA0 low) or 0x4B (SA0 high); bootloader 0x28 / 0x29
Transactions Plain writes and reads, no register address, no repeated start
Pull-ups 2 kΩ to 4 kΩ on SCL and SDA, to VDDIO
No data BNO085 stretches SCL until it has data; BNO086 sends an empty (zero-length) transfer
Setting Value
Mode Mode 3 (CPOL = 1, CPHA = 1), MSB first, 4-wire
Speed Up to 3 MHz
Chip select H_CSN low for a whole transfer; H_INTN deasserts within 800 ns of CS
Wake Drive PS0/WAKE low; the hub asserts H_INTN within about 150 µs, then clock the transfer
Strapping PS0 and PS1 high from before reset until the first H_INTN; PS0 must be a GPIO
Setting Value
Format 3 Mbit/s, 8 data bits, no parity, 1 stop bit
Host to chip At least 100 µs between bytes
Clock External 32.768 kHz crystal or clock required: the internal oscillator is not accurate enough
Setting Value
Format 115200 bit/s, 8 data bits, no parity, 1 stop bit
Direction Chip to host only: one 19-byte frame every 10 ms (100 Hz)
Clock External 32.768 kHz crystal or clock required

The frame format is on the UART-RVC mode page.

The SH-2 traffic itself is CEVA's Sensor Hub Transport Protocol (SHTP): every transfer starts with a 4-byte header (length, channel, sequence). On I2C each read starts at the header again, which is why the port reads the header first and then the whole transfer.

Start-up and interrupt timing

sequenceDiagram
    participant H as Host (driver)
    participant C as BNO08x
    H->>C: NRST low, at least 10 ns (HardwareReset() holds 2 ms)
    Note over C: PS0, PS1, BOOTN, SA0 sampled
    H->>C: NRST high
    Note over C: internal initialisation t1 >= 90 ms, then about 4 ms of configuration
    C-->>H: H_INTN low (I2C / SPI), or an advertisement message (UART)
    H->>C: read the transfer (I2C address byte or SPI CS)
    C-->>H: H_INTN high within 10 µs (I2C) / 800 ns (SPI)
Parameter Value Source
NRST low time at least 10 ns datasheet figure 6-8
Reset to first H_INTN at least 90 ms + about 4 ms figure 6-8
Respond to H_INTN within about 10 ms, then the hub gives up and retries section 1.2.4.1
Wake to H_INTN (SPI) about 150 µs figure 6-12

Handle H_INTN within a tenth of your fastest report period: late responses starve the fusion processing and add errors. HardwareReset() waits RESET_STARTUP_MS (94 ms: t1 at least 90 ms plus t2 about 4 ms) after releasing NRST, so the hub has finished its start-up before the first transfer.

Power

Supply Range Notes
VDD (sensors) 2.4 V to 3.6 V Must reach its level before or together with VDDIO
VDDIO (core and I/O) 1.7 V to 3.6 V Sets the logic levels of every pin
CAP (pin 9) 100 nF to GND External capacitor

Typical consumption, measured by CEVA over SPI at VDDIO 3 V and VDD 3.3 V: 0.39 mW idle, about 35 mW for 100 Hz 9-axis fusion and about 46 mW for the gyro-integrated rotation vector at 1 kHz. ENV_SCL and ENV_SDA (pins 15, 16) need pull-ups even with no environmental sensor fitted, because the firmware probes them at reset.

Errata and traps that affect the host

Respond to H_INTN

The BNO085 and BNO086 retry a transfer the host did not collect within about 10 ms. A host that polls slowly sees lost reports and degraded fusion. Wire H_INTN, make DataAvailable() read it, and call Update() often.

  • I2C clock stretching. A BNO085 polled with no data holds SCL low until it has some. Gate reads on H_INTN, and give your I2C peripheral a clock-stretch timeout longer than your slowest report period.
  • UART needs a crystal. UART-SHTP and UART-RVC do not work reliably on the internal oscillator.
  • Bootloader address. In the bootloader the I2C address moves to 0x28 / 0x29; the driver switches a port that has the I2C address hooks there for the transfer (see Firmware update).

Evaluation setup

The ESP32 examples run on an ESP32-S3 with a BNO08x breakout, over I2C unless noted:

Signal ESP32-S3 GPIO
SDA, SCL 4, 5 (400 kHz, address 0x4B first, then 0x4A)
H_INTN 17
NRST 16
SPI SCLK, MOSI, MISO, CS 12, 11, 13, 10 (spi_polling; mode 3, 3 MHz)
PS0/WAKE 18 (spi_polling; PS1 strapped high)
UART TX, RX 21, 20 (uart_shtp_polling at 3 Mbit/s, PS1 high and PS0 low; rvc_mode at 115200, PS1 low and PS0 high)

The pin assignment lives in esp32_bno08x_test_config.hpp.

Reference documents

Document What it is for
BNO08X datasheet Pins, interfaces, timing, report rates, electrical limits
SH-2 reference manual Report formats, Q-points, commands, FRS records
SHTP specification Transfer header, channels, framing on each bus
CEVA SH-2 library The host library in src/sh2