Skip to content

Commit a72e7b3

Browse files
committed
Fix generic Linux SPI write_readinto slice
1 parent ddc4686 commit a72e7b3

2 files changed

Lines changed: 64 additions & 4 deletions

File tree

src/adafruit_blinka/microcontroller/generic_linux/spi.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ def readinto(self, buf, start=0, end=None, write_value=0):
113113
def write_readinto(
114114
self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
115115
):
116-
"""Perform a half-duplex write from buffer_out and then
117-
read data into buffer_in
118-
"""
116+
"""Write to and read from SPI at the same time."""
119117
if buffer_out is None or buffer_in is None:
120118
return
121119
if len(buffer_out) < 1 or len(buffer_in) < 1:
@@ -132,7 +130,7 @@ def write_readinto(
132130
self._spi.max_speed_hz = self.baudrate
133131
self._spi.mode = self.mode
134132
self._spi.bits_per_word = self.bits
135-
data = self._spi.transfer(list(buffer_out[out_start : out_end + 1]))
133+
data = self._spi.transfer(list(buffer_out[out_start:out_end]))
136134
for i in range((in_end - in_start)):
137135
buffer_in[i + in_start] = data[i]
138136
# self._spi.close()

tests/test_generic_linux_spi.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# SPDX-FileCopyrightText: 2026 Melissa LeBlanc-Williams for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
import sys
5+
import types
6+
from unittest import mock
7+
8+
9+
class FakePureIOSPI:
10+
last_instance = None
11+
12+
def __init__(self, device):
13+
self.device = device
14+
self.max_speed_hz = None
15+
self.mode = None
16+
self.bits_per_word = None
17+
self.transfers = []
18+
FakePureIOSPI.last_instance = self
19+
20+
def transfer(self, data):
21+
self.transfers.append(data)
22+
return [value + 0x10 for value in data]
23+
24+
25+
class FakeDetector:
26+
class Chip:
27+
id = "test-chip"
28+
29+
class Board:
30+
id = "test-board"
31+
32+
chip = Chip()
33+
board = Board()
34+
35+
36+
fake_platformdetect = types.ModuleType("adafruit_platformdetect")
37+
fake_platformdetect.Detector = lambda: FakeDetector()
38+
sys.modules.setdefault("adafruit_platformdetect", fake_platformdetect)
39+
40+
fake_pureio = types.ModuleType("Adafruit_PureIO")
41+
fake_pureio.spi = types.SimpleNamespace(SPI=FakePureIOSPI)
42+
sys.modules.setdefault("Adafruit_PureIO", fake_pureio)
43+
44+
# pylint: disable=wrong-import-position
45+
from adafruit_blinka.microcontroller.generic_linux import spi as generic_linux_spi # noqa: E402
46+
47+
48+
@mock.patch.object(generic_linux_spi.spi, "SPI", FakePureIOSPI)
49+
def test_write_readinto_uses_exclusive_out_end():
50+
FakePureIOSPI.last_instance = None
51+
spi = generic_linux_spi.SPI((0, 0))
52+
spi.init(baudrate=1000000, polarity=1, phase=1, bits=8)
53+
54+
buffer_out = bytearray([0x10, 0x20, 0x30, 0x40])
55+
buffer_in = bytearray([0x00, 0x00, 0x00, 0x00])
56+
57+
spi.write_readinto(
58+
buffer_out, buffer_in, out_start=1, out_end=3, in_start=1, in_end=3
59+
)
60+
61+
assert FakePureIOSPI.last_instance.transfers == [[0x20, 0x30]]
62+
assert buffer_in == bytearray([0x00, 0x30, 0x40, 0x00])

0 commit comments

Comments
 (0)