Skip to content

I2C Slave: Wire.write() corrupts data after first transmission on SAMD21 #75

@tarasfilonenko

Description

@tarasfilonenko

Description

When using the XIAO SAMD21 as an I2C slave, Wire.write() in the onRequest callback works correctly for the first transmission, but subsequent transmissions are corrupted - the first byte is repeated for all 32 bytes.

Hardware

Board: Seeeduino XIAO SAMD21
Core version: 1.8.5
Master: ESP32-C3
Steps to Reproduce
Configure XIAO SAMD21 as I2C slave with Wire.begin(address)
Register onRequest callback that writes 32 bytes using Wire.write(buffer, 32)
Have master request data multiple times
Expected Behavior
Each requestFrom() should receive the correct 32 bytes from the slave.

Actual Behavior

1st request: Correct data received (e.g., 0x2a, 0x01, 0x02, 0x09, 0x05, ...)
2nd request: First byte repeated 31 times + 0xff (e.g., 0x2a, 0x2a, 0x2a, ... 0x2a, 0xff)
3rd+ requests: All 0xff bytes
Workarounds Attempted (None Worked)
Using volatile for the TX buffer
Copying to stack-local buffer before Wire.write()
Writing byte-by-byte instead of buffer
Pre-filling Wire buffer outside ISR
Reinitializing Wire after each transmission
Root Cause
The onService() function in Wire.cpp likely has issues with buffer state management between transactions. The Arduino SAMD core addressed similar issues in PR arduino#605:

arduino#605

Suggested Fix

Port the fixes from ArduinoCore-samd PR arduino#605 to this repository.

Minimal Reproduction Code

#include <Wire.h>

uint8_t txBuffer[32];

void onRequest() {
Wire.write(txBuffer, sizeof(txBuffer));
}

void setup() {
for (int i = 0; i < 32; i++) txBuffer[i] = i + 1;
Wire.begin(0x01);
Wire.onRequest(onRequest);
}

void loop() {}

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions