Skip to content

Detect the DPS310 on both of its I2C addresses - #11906

Merged
sensei-hacker merged 6 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/dps310-address-detect
Oct 4, 2026
Merged

sensei-hacker merged 6 commits into
iNavFlight:maintenance-10.xfrom
Raffi1202:fix/dps310-address-detect

Conversation

@Raffi1202

@Raffi1202 Raffi1202 commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Problem

A DPS310 wired for I2C address 0x77 is not detected (#9958). The sensor answers on 0x77 with SDO high (the default on breakout boards) and on 0x76 with SDO pulled to GND, but common_hardware.c registers only 0x76 unless a target defines DPS310_I2C_ADDR. Users in #9958 report a board with the DPS310 on 0x77 that only worked after editing the target, and an external DPS310 that was never found. Only targets that pin the address themselves (BRAHMA_F405/F722) work on 0x77 today.

Change

  • bus.h: DEVHW_DPS310 becomes DEVHW_DPS310_0 / DEVHW_DPS310_1, the same pattern as DEVHW_IST8310_0/1. The enum is internal (not sent over MSP or stored in config).
  • common_hardware.c: without DPS310_I2C_ADDR both 0x76 and 0x77 are registered. A target that defines the address keeps one descriptor (BRAHMA_F405/F722, ORBITH743); the SPI path stays a single slot.
  • barometer_dps310.c: baroDPS310Detect() probes both registered slots within the same five ID reads 100 ms apart that maintenance-10.x uses for 0x76 alone, reading 0x76 before 0x77 in every round. Each address keeps the full maintenance-10.x retry window, and probing the second address adds no boot time. A slot whose chip ID matches but whose configure fails is de-initialised and dropped; the unused slot is de-initialised at the end.
  • HUMMINGBIRD_FC305/target.c (own descriptor table) uses the _0 slot; inav_enums.json / inav_enums_ref.md carry the renumbered devHardwareType_e entries (regenerated, DPS310 delta only).

0x76 is read first in every round, so boards that work today see no change in detection or timing.

Test

No hardware with a DPS310 on 0x77 here. The real barometer_dps310.c was linked into a host harness with a fake I2C bus (device models on 0x76/0x77 with injected failed transfers, NACK until a given time, or a wrong ID for the first reads; virtual time from the start of baroDPS310Detect()). Time spent in baroDPS310Detect():

Bus maintenance-10.x previous revision (a139d9c) this revision
nothing on 0x76/0x77 500 ms 200 ms 500 ms
DPS310 on 0x76 180 ms, found 180 ms, found 180 ms, found
DPS310 on 0x77 not found 280 ms, found 180 ms, found
DPS310 on both 0x76 0x76 0x76
DPS310 on 0x76, first 1 / 2 / 4 transfers fail found (280 / 380 / 580 ms) found / not found / not found found (280 / 380 / 580 ms)
DPS310 on 0x76, first 5 transfers fail not found not found not found
DPS310 on 0x76, no answer for the first 450 ms found (580 ms) not found found (580 ms)
DPS310 on 0x77, first 4 transfers fail not found not found found (580 ms)
DPS310 on 0x76, ID reads 0x00 four times found (580 ms) found (580 ms) found (580 ms)
SPL07-003 on 0x77 not found found found
BMP280 on 0x76, DPS310 on 0x77 not found 680 ms, found 180 ms, found
BMP280 on 0x77, nothing on 0x76 500 ms, not probed 600 ms, not found 500 ms, not found
target pins 0x77, nothing there 500 ms 100 ms 500 ms

For 0x76 and for a pinned single address, every row matches maintenance-10.x. The previous revision gave up on an address after two back-to-back failed reads; the bus layer reports an empty address and a chip that does not answer the same way (busReadBuf() returns false, and the HAL and AT32 I2C drivers treat a NACK as a hardware failure and re-init the bus), so a per-read fast reject cannot keep the retry window for a present chip.

Two DPS310s on one bus where the one on 0x76 misses a round while the one on 0x77 answers: the 0x77 sensor is taken.

A foreign chip on 0x77 whose register 0x0D reads 0x10 passes the ID check: in the worst case, a BMP388 whose SENSORTIME_1 register happens to read 0x10, deviceConfigure() writes the soft-reset bits to register 0x0C (SENSORTIME_0 on the BMP388) before its status check rejects the chip. This only matters when that chip's own driver does not find it first: in autodetect the MS5611, MS5607 and BMP085 drivers probe 0x77 before the DPS310 driver, while the BMP280, BMP388 and SPL06 drivers probe only 0x76 unless the target sets their address.

Known limit, unchanged by this PR: the SPL06-001 also reports ID 0x10 in register 0x0D. In autodetect the SPL06 driver runs before the DPS310 driver, so a sensor on 0x76 is claimed by the SPL06 driver as before; an SPL06 on 0x77 (not probed by the SPL06 driver) would now be picked up by the DPS310 driver.

Built with -DWARNINGS_AS_ERRORS=ON, no warnings: SITL and MATEKF722 for this revision (6d2505d); MATEKF405, IFLIGHT_BLITZ_ATF435, MATEKH743, HUMMINGBIRD_FC305 (own descriptor table), DAKEFPVF405 (DPS310 on SPI) and BRAHMA_F405 (DPS310_I2C_ADDR 0x77) for the previous revision.

Flash / RAM (arm-none-eabi-size)

MATEKF722, this revision (6d2505d) against maintenance-10.x 3931fcd and against the previous revision a139d9c:

Flash (text+data) RAM (bss)
vs maintenance-10.x +220 B +32 B
vs previous revision +144 B 0

Previous revision against maintenance-10.x (for reference): MATEKF722 +76 B / +32 B, MATEKF405 +284 B / +32 B, IFLIGHT_BLITZ_ATF435 +252 B / +32 B.

On targets with both addresses registered, the RAM is the second busDevice_t (32 B) for the 0x77 slot and the extra descriptor is 12 B of flash.

Docs

No user-facing documentation states the DPS310 default address. DPS310_I2C_ADDR in a target still pins one address, as described in docs/development/targets/common-issues.md.

The DPS310 answers on 0x77 when its SDO pin is pulled high and on 0x76 when
it is pulled low. Both wirings are shipped on real boards, so the fixed
default of 0x76 left every board of the other kind without a barometer.

Register both addresses and probe them in the driver, the same way the
IST8310 compass is handled. A target that pins the address down with
DPS310_I2C_ADDR keeps using only that address.

Fixes iNavFlight#9958
@Raffi1202
Raffi1202 marked this pull request as ready for review September 11, 2026 15:54
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Detect DPS310 barometers at both valid I2C addresses

🐞 Bug fix ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Registers both valid DPS310 I2C addresses when targets do not pin one.
• Iterates registered DPS310 slots, configuring the first detected sensor.
• Preserves explicit target addresses and existing SPI behavior.
Diagram

graph TD
    A["Target config"] --> B{"Address pinned?"}
    B -->|Yes| C["Single descriptor"] --> E["DPS310 probe loop"] --> F{"Chip detected?"} -->|Yes| G["Configure barometer"]
    B -->|No| D["Dual descriptors"] --> E
    F -->|No| H["Try next slot"] --> E
Loading
High-Level Assessment

The current approach is appropriate because it reuses the established multi-slot bus-descriptor pattern already used by IST8310 and preserves target-specific address overrides. Directly scanning raw I2C addresses in the driver would bypass the bus registry, while changing the single default address would merely reverse which boards fail.

Files changed (4) +25 / -15

Bug fix (2) +16 / -10
barometer_dps310.cProbe both registered DPS310 hardware slots +14/-9

Probe both registered DPS310 hardware slots

• Replaces single-slot initialization with an ordered loop over both DPS310 device identifiers. Failed candidates are deinitialized, while the first successfully detected and configured device is retained.

src/main/drivers/barometer/barometer_dps310.c

bus.hDefine two DPS310 hardware identifiers +2/-1

Define two DPS310 hardware identifiers

• Splits the DPS310 bus hardware identifier into consecutive '_0' and '_1' slots, allowing the driver to iterate over two registered addresses.

src/main/drivers/bus.h

Other (2) +9 / -5
target.cMigrate custom DPS310 descriptor to slot zero +1/-1

Migrate custom DPS310 descriptor to slot zero

• Renames the target-owned DPS310 descriptor and hardware identifier to the new '_0' convention while retaining its configured address.

src/main/target/HUMMINGBIRD_FC305/target.c

common_hardware.cRegister both default DPS310 I2C addresses +8/-4

Register both default DPS310 I2C addresses

• Registers descriptors for 0x76 and 0x77 when no target-specific address is defined. Explicit address overrides still create one descriptor, and SPI registration remains a single slot.

src/main/target/common_hardware.c

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Hardware values are documented wrong ✓ Resolved
Description
devHardwareType_e adds a second DPS310 enumerator, but the checked-in enum JSON and reference
still contain the removed single entry and the old numbering. Whenever these artifacts are consumed,
they report a nonexistent DPS310 name and values one lower than the source for every subsequent
hardware type.
Code

src/main/drivers/bus.h[R101-102]

+    DEVHW_DPS310_0,
+    DEVHW_DPS310_1,
Evidence
The source enum now assigns consecutive values to two DPS310 entries before B2SMPB, while both
generated artifacts retain the removed name and old numbering. Repository guidance explicitly
requires regeneration when a source enum changes and notes that CI will not detect stale output.

src/main/drivers/bus.h[93-106]
docs/development/msp/inav_enums.json[829-840]
docs/development/msp/inav_enums_ref.md[1456-1465]
docs/development/Development.md[164-173]
docs/development/msp/README.md[11-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new DPS310 enum entry shifts all subsequent hardware values, but the checked-in generated enum artifacts still expose the old name and numbering.
## Fix Focus Areas
- src/main/drivers/bus.h[101-102]
- docs/development/msp/inav_enums.json[829-840]
- docs/development/msp/inav_enums_ref.md[1456-1465]
## Recommended Fix
Run `docs/development/msp/gen_docs.sh` from its directory and commit all regenerated enum documentation outputs so they contain both DPS310 entries and the corrected subsequent values.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/main/drivers/bus.h
@sensei-hacker sensei-hacker added this to the 10.0 milestone Sep 20, 2026
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

RAM / Flash usage vs. base commit f1cd5c6 — commit 6d2505d

Using the nearest available size baseline — the PR's exact base commit has no stored baseline yet.

Target Flash Δ RAM Δ
MATEKF405 +972 B (+0.13%) CCM: ±0 B (±0.00%)
RAM: +32 B (+0.03%)
MATEKF722 +204 B (+0.04%) ITCM_RAM: ±0 B (±0.00%)
RAM: +32 B (+0.04%)
TCM: ±0 B (±0.00%)
MATEKF765 +1100 B (+0.15%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: +24 B (+0.02%)
MATEKH743 +1108 B (+0.14%) D2_RAM: ±0 B (±0.00%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: ±0 B (±0.00%)
RAM: +32 B (+0.02%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Test firmware build ready — commit 6d2505d

Download firmware for PR #11906

251 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@b14ckyy

b14ckyy commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Looks good, CI is green on all targets. Two points:

  • deviceDetect() retries five times with 100 ms delay even on a NACK, so with two addresses a board without any baro now spends a full second there during boot. Stopping on a NACK would avoid that.
  • The MSP catalogue entries for other PRs in the docs diff will collide with every other PR doing the same; better to sync the catalogue once on maintenance-10.x.

We can merge after this is addressed. Thank you!

@b14ckyy b14ckyy assigned b14ckyy and Raffi1202 and unassigned b14ckyy Sep 23, 2026
@b14ckyy b14ckyy added Bugfix Feedback required The issue/PR is missing information to proceed further labels Sep 23, 2026
deviceDetect() retried the ID read five times with a 100 ms delay even
when the address did not answer. With both 0x76 and 0x77 registered, a
board without a DPS310 spent a full second there during boot.

A failed read is now repeated once right away, because busReadBuf()
also fails on a bus error that the I2C driver has just recovered from.
Only after a second failed read is the address given up; an answer with
a foreign chip ID still gets the 100 ms retries.

Also drop the duplicate address comment in the driver and shorten the
one in common_hardware.c to one line.
@Raffi1202

Copy link
Copy Markdown
Contributor Author

@b14ckyy both points are addressed in bfff803 and a139d9c:

  • NACK: deviceDetect() now gives up on an address after a second failed ID read, so an empty address costs one 100 ms wait instead of five. The second read runs right away without a delay, because busReadBuf() also returns false for a bus error the I2C driver has just reset. An answer with a foreign chip ID still gets the retries. Host harness with the real driver and a fake I2C bus, boot delay spent in baroDPS310Detect():

    Bus before (PR) now
    nothing on 0x76/0x77 1000 ms 200 ms
    DPS310 on 0x76 180 ms 180 ms
    DPS310 on 0x77 680 ms 280 ms
    DPS310 whose first transfer fails found found

    (maintenance-10.x today: 500 ms with no sensor.) The whole PR costs +76 B flash / +32 B RAM on MATEKF722 against current maintenance-10.x.

  • MSP catalogue: merged maintenance-10.x, which already carries the same entries, so they are gone from the diff. The PR now touches the DPS310 driver, bus.h, common_hardware.c, the HUMMINGBIRD_FC305 descriptor and the renumbered devHardwareType_e entries in inav_enums.json / inav_enums_ref.md.

@sensei-hacker

Copy link
Copy Markdown
Member

I took a look at this with an AI-based tool I have. It may well be wrong on the point below — please treat it as a question to check rather than a verdict, and correct me if I've misread something.

deviceDetect() retry loop — does it still tolerate a slow-to-respond chip?

In the new deviceDetect(), when both the initial read and the immediate back-to-back retry fail, it does return false directly — which exits the function entirely rather than continuing on to the next of the 5 spaced, 100 ms-apart retries. Before this change, a single failed read just fell through to the next retry, so the loop tolerated up to 5 consecutive failures spread over ~500 ms.

Could this mean a real DPS310 that's simply slow to come up right after power-on or an I2C bus reset — the same "bus glitch" scenario the comment above it calls out — might now fail detection after only ~100-200 ms, instead of the original ~500 ms window? The test table in the PR description only shows "first transfer fails" (singular) succeeding, so I'm not sure this case is covered.

Would changing the inner if (!ack) { return false; } to if (!ack) { continue; } preserve the fast-reject for genuinely empty addresses while keeping the original retry tolerance for a real, slow chip? Curious whether the early exit was intentional or just fell out of reusing the existing loop structure for the new fast-path.

The previous revision gave up on an address after two back-to-back
failed ID reads, so a DPS310 that missed both was never retried, while
maintenance-10.x tolerates four failed reads spread over 500 ms. The bus
layer reports an empty address and a chip that does not answer the same
way, so the two cannot be told apart per read.

Probe 0x76 and 0x77 in the same five 100 ms retries instead, 0x76 first.
Each address keeps the maintenance-10.x retry window, and a bus without
a DPS310 costs 500 ms as before instead of 1000 ms for two sequential
probes.
@Raffi1202

Copy link
Copy Markdown
Contributor Author

@sensei-hacker Your reading is right. The early exit was intended (it was the NACK stop b14ckyy asked for), but it cut the tolerance from four failed reads spread over 500 ms to two back-to-back reads. continue would not keep the fast reject, though: the return false is the fast reject, so with continue an empty address costs the full 500 ms again, 1000 ms with both addresses. The bus layer cannot tell an empty address from a chip that does not answer yet: both make busReadBuf() return false, and the HAL and AT32 I2C drivers treat a NACK as a hardware failure and re-init the bus.

Changed in 6d2505d: deviceDetect() is a single ID read again, and baroDPS310Detect() probes 0x76 and 0x77 within the same five reads 100 ms apart, 0x76 first in every round. Each address gets exactly the maintenance-10.x window, and the second address adds no boot time.

Host harness (the real driver against a fake I2C bus, virtual time), time in baroDPS310Detect():

Bus maintenance-10.x previous revision with continue 6d2505d
nothing on 0x76/0x77 500 ms 200 ms 1000 ms 500 ms
DPS310 on 0x77 not probed 280 ms 680 ms 180 ms
DPS310 on 0x76, first 2 / 4 transfers fail 380 / 580 ms not found 280 / 380 ms 380 / 580 ms
DPS310 on 0x76, no answer for 450 ms 580 ms not found 580 ms 580 ms
DPS310 on 0x77, first 4 transfers fail not probed not found 880 ms 580 ms

For 0x76 alone and for targets that pin one address, every case matches maintenance-10.x. The empty-bus case goes back from 200 ms to the 500 ms of maintenance-10.x. MATEKF722: +144 B flash against the previous revision, +220 B flash / +32 B RAM against maintenance-10.x. Full table in the PR description.

@sensei-hacker
sensei-hacker merged commit 25e2b2b into iNavFlight:maintenance-10.x Oct 4, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bugfix Feedback required The issue/PR is missing information to proceed further

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants