Summary
On Particle Muon (RTL8722DM / msom), when reading 30 bytes from an I2C device behind a PCA9546A mux, Wire.requestFrom(addr, 30) returns 30 but every 3rd byte (indices 2, 5, 8, 11, …) is wrong. The 1st and 2nd byte of each 3-byte group look correct. This points to a HAL or DMA stride/alignment bug in the I2C RX path, not application or bus wiring.
Environment
- Device: Particle Muon (RTL8722DM), platform
msom - Device OS version: 6.3.4
- Setup: Sensirion SPS30 (0x69) on I2C behind NXP PCA9546A (0x70) on channel 0. Same bus: 50 kHz,
endTransmission(true), 500 µs delay after mux select. - Repro: Minimal app (no SPS30 library): set pointer 0x0300, delay 100 ms, mux select + 500 µs,
requestFrom(0x69, 30), then 30×Wire.read().
Expected behavior
SPS30 returns 10 × (2 data bytes + 1 CRC byte) = 30 bytes. Sensirion CRC-8 (poly 0x31) over each 2-byte pair should match the 3rd byte. On other platforms (e.g. generic esp32/arduino) the same sequence yields all CRCs OK.
Actual behavior
requestFrom(0x69, 30)returns 30 (no truncation).- Raw 30 bytes are identical on every read (not random noise).
- All 10 CRCs fail. The 3rd byte of each triplet (the CRC byte) is wrong; the first two bytes of each triplet look plausible (e.g.
01 01,00 00,13 3C, …).
Example raw frame (repeated every read):
01 01 00 00 00 00 00 00 00 00 00 40 13 3C E0 26 00 9C 75 00 23 00 00 00 00 22 00 00 00 F0
- Word 0: data
01 01, expected CRC0x44, got0x00 - Word 1: data
00 00, expected CRC0x81, got0x00 - Word 2: data
00 00, expected CRC0x81, got0x00 - Word 3: data
00 00, expected CRC0x81, got0x40 - Words 4–9: data bytes look reasonable; CRC bytes still do not match computed CRC.
So indices 2, 5, 8, 11, … (every 3rd byte) are corrupted or replaced; indices 0,1, 3,4, 6,7, … look correct. This is consistent with a HAL/DMA copy or buffer layout bug that affects every 3rd byte (e.g. 32-bit vs 24-bit alignment or wrong stride).
Notes
- Muon HAL I2C buffer size (256 bytes) is not the cause; 30 < 256 and the issue is value corruption, not length.
- Mux timing (500 µs after select) and 50 kHz clock are applied; flushing Wire RX and 100 ms delay between set-pointer and read do not fix the corruption.
- Workaround attempt: Reading in 10 separate
requestFrom(addr, 3)transactions (one Sensirion word per transaction) still yields the same corrupted frame and all CRCs BAD. So the bug affects even 3-byte reads, not only longer ones. - Pull-ups: 2.2 kΩ added on mux downstream (SDA and SCL to 3.3 V). Raw frame changed slightly (e.g. different leading byte) but all 10 CRCs still BAD. Confirms corruption is HAL, not bus level.
Request
Please check the RTL8722 I2C HAL (and any DMA or buffer handling used for requestFrom / read path) for a stride or alignment bug that could corrupt every 3rd received byte. If possible, suggest a workaround or HAL patch for Muon.
Minimal repro code
Can be provided on request (Particle app: set pointer 0x0300, requestFrom(0x69, 30), 30× read, Sensirion CRC check, no external library).
