drivers: `I2C_Device.Address.check_reserved` rejects 0x08-0x0F and accepts 0x04-0x07 (HighSpeedMaster range is off by one bit)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Newbie friendliness
- 69/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- zig
- Domain
- embedded-iot
Research direction
Start in drivers/src/base/I2C_Device.zig at Address.check_reserved and read the existing test table in the same file. The issue gives the incorrect and expected address ranges and a host-only reproduction. Update the range check and its test expectations, then run the reproduction or zig build test from drivers/; done when 0x04–0x07 are rejected and 0x08–0x0F are accepted.
Written by the indexing model from the issue text.
Description
Summary
Address.check_reserved (drivers/src/base/I2C_Device.zig:55 on master) returns
error.HighSpeedMaster for 0b0001000...0b0001111 (0x08-0x0F). The Hs-mode
controller code is 0000 1XX, i.e. 0x04-0x07 — the page the doc comment links
(https://www.i2c-bus.org/addressing/ lists 00001XX X as "High-Speed Master
Code"), and the doc comment itself: "Reserved addresses are ones that match
0b0000XXX or 0b1111XXX". So:
- 0x08-0x0F, ordinary 7-bit addresses, are refused. Through the rp2xxx HAL every
read (.dont_allow_reserved) returnserror.IllegalAddressfor them before
anything reaches the bus. A bus scan that starts at 0x08 (the usual first
address) sees an error rather than a NACK at its first address. The same check runs
in the nrf5x, stm32 (i2c_v2) and espressif HALs. Real parts live at these
addresses. One is the AK09916 magnetometer at 0x0C: the in-treeICM_20948
driver names itMAG_ADDRESS = 0x0C. That driver reaches it through the ICM's own
aux I2C master, so it is unaffected, but on a board that wires the AK09916 straight
to the host bus the HAL refuses its address. - 0x04-0x07, the reserved Hs-mode codes, are accepted.
It is a regression from #648 (c058aa4, 2025-08-16). The bool version it
replaced was ((value & 0x78) == 0) or ((value & 0x78) == 0x78), which was right.
When that became a switch, 0000 1XX was written as 0001 XXX, and the new test table
encoded the same values (0x08 and 0x0F expect HighSpeedMaster).
Versions
| tree | toolchain | result |
|---|---|---|
microzig 0.15.1 release (mz_drivers-0.0.1-bvRa3F…) |
zig 0.15.2 | reproduces (rc=1) |
| microzig master f36d59fb7b22 (tag 0.17.17, 2026-10-10) | zig 0.17.0 | reproduces (rc=1) |
| master + the fix below | zig 0.17.0 | fixed (rc=0) |
Repro (host-only, no hardware)
repro.zig:
const std = @import("std");
const Address = @import("I2C_Device").Address;
fn reserved(a: u7) bool {
const addr: Address = @enumFromInt(a);
addr.check_reserved() catch return true;
return false;
}
test "0x04-0x07 (0000 1XX, Hs-mode controller code) are reserved" {
for ([_]u7{ 0x04, 0x05, 0x06, 0x07 }) |a| try std.testing.expect(reserved(a));
}
test "0x08-0x0F are ordinary addresses" {
for ([_]u7{ 0x08, 0x09, 0x0C, 0x0F }) |a| try std.testing.expect(!reserved(a));
}
zig test repro.zig --dep I2C_Device -Mroot=repro.zig -MI2C_Device=<microzig>/drivers/src/base/I2C_Device.zig
Expected: both tests pass.
Actual (master f36d59f, zig 0.17.0):
1/2 repro.test.0x04-0x07 (0000 1XX, Hs-mode controller code) are reserved...0x04 accepted, expected reserved
FAIL (TestUnexpectedResult)
2/2 repro.test.0x08-0x0F are ordinary addresses...0x08 rejected, expected usable
FAIL (TestUnexpectedResult)
0 passed; 0 skipped; 2 failed.
Fix
One switch arm, plus the two test-table rows that encoded the wrong range:
- 0b0001000...0b0001111 => return Address.Error.HighSpeedMaster,
+ 0b0000100...0b0000111 => return Address.Error.HighSpeedMaster,
and the existing test in the same file now expects HighSpeedMaster at 0x04/0x07 and
"valid" at 0x08/0x0F. With the patch, zig build test in drivers/ gives
123/123 tests passed (rc=0), the same count as unpatched master. The repro above
passes.
Behaviour change worth a line in the release notes: callers that pass 0x04-0x07
with .dont_allow_reserved / .allow_general now get IllegalAddress, and
0x08-0x0F start working.
I have the patch ready and can open it as a PR if you'd like.
- Dominant language
- Zig
- Stars
- 2.3k
- Forks
- 198
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 23
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ZigEmbeddedGroup/microzig
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
ZigEmbeddedGroup/microzig#1086 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
ZigEmbeddedGroup/microzig#1061 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
ZigEmbeddedGroup/microzig#1059 · 1 comment ·
Maintainers usually reply within 1 day
-
regz: AVR peripherals generated at address 0 when the register-group name matches the module (ATDF)Possibly taken @matpala claimed this 3 days ago. Open
Difficulty 4/5 3-5 days Newbie friendliness 48/100
ZigEmbeddedGroup/microzig#1072 ·
Maintainers usually reply within 1 day
-
AVR (ATmega328P): UART/SPI HAL, drivers.zig, and nRF24L01+ driver (Emakefun RF-Nano V3.0)Possibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 5/5 Over a week Newbie friendliness 35/100
ZigEmbeddedGroup/microzig#1069 · 3 comments ·
Maintainers usually reply within 1 day
All issues in ZigEmbeddedGroup/microzig
Similar issues
-
Examples say cnxOpendocumentation embedded
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
rusefi/rusefi#10401 · 3 comments ·
Maintainers usually reply within 1 day
-
Fw::Time::add(F64) asserts when the fraction rounds up to a full second and the time already holds 999999 microsecondsPossibly taken @auraseb claimed this 1 day ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 63/100
meshcore-dev/MeshCore#3622 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100