From bc3cba1cf84abc4d0db940be57b97e095443434f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:48:59 +0000 Subject: [PATCH 1/2] Initial plan From 88b37cdf599d83b4b40c2b3079a82377e1cc2fa2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:55:11 +0000 Subject: [PATCH 2/2] Fix SpiAdapter.Read to use equal-length buffers for TransferFullDuplex TransferFullDuplex requires writeBuffer and readBuffer to have the same length. The Read method was creating a 2-byte writeBuffer and a (buffer.Length + 2)-byte readBuffer, causing ArgumentException on real SPI devices. Fix: allocate writeBuffer with the same size as readBuffer, placing OpCode and register address in the first two bytes (remaining bytes are don't-care for the SPI read operation). Also fix the test mock's TransferFullDuplex to only pass command bytes to Write, preventing don't-care padding from corrupting register data. Agent-Logs-Url: https://github.com/dotnet/iot/sessions/7c410060-a096-49b1-8cfa-348f86e1f77b Co-authored-by: krwq <660048+krwq@users.noreply.github.com> --- src/devices/Mcp23xxx/SpiAdapter.cs | 17 +++++++---------- src/devices/Mcp23xxx/tests/Mcp23xxxTest.cs | 5 ++++- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/devices/Mcp23xxx/SpiAdapter.cs b/src/devices/Mcp23xxx/SpiAdapter.cs index f2b077b54e..ce58cd38bf 100644 --- a/src/devices/Mcp23xxx/SpiAdapter.cs +++ b/src/devices/Mcp23xxx/SpiAdapter.cs @@ -37,18 +37,15 @@ public SpiAdapter(SpiDevice device, int deviceAddress) /// public override void Read(byte registerAddress, Span buffer) { - // Include OpCode and Register Address. - Span writeBuffer = stackalloc byte[] - { - GetOpCode(_deviceAddress, isReadCommand: true), - registerAddress - }; + int fullLength = buffer.Length + 2; - Span readBuffer = stackalloc byte[buffer.Length + 2]; + // Include OpCode and Register Address. + // writeBuffer must be the same length as readBuffer for TransferFullDuplex. + Span writeBuffer = stackalloc byte[fullLength]; + writeBuffer[0] = GetOpCode(_deviceAddress, isReadCommand: true); + writeBuffer[1] = registerAddress; - // Should this also contain the op code and register? - // Why are we transferring full duplex if we only really - // need to read? + Span readBuffer = stackalloc byte[fullLength]; _device.TransferFullDuplex(writeBuffer, readBuffer); // First 2 bytes are from sending OpCode and Register Address. diff --git a/src/devices/Mcp23xxx/tests/Mcp23xxxTest.cs b/src/devices/Mcp23xxx/tests/Mcp23xxxTest.cs index d787000d44..6ef22fb71e 100644 --- a/src/devices/Mcp23xxx/tests/Mcp23xxxTest.cs +++ b/src/devices/Mcp23xxx/tests/Mcp23xxxTest.cs @@ -71,7 +71,10 @@ public SpiDeviceMock(int ports) public override void TransferFullDuplex(ReadOnlySpan writeBuffer, Span readBuffer) { - Write(writeBuffer); + // Only pass the command bytes (OpCode + RegisterAddress) to Write. + // Remaining bytes in writeBuffer are don't-care padding for full-duplex reads + // and should not be written as register data. + Write(writeBuffer.Slice(0, Math.Min(writeBuffer.Length, 2))); Read(readBuffer); }