Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
only use full_buffer for i2c.write(). Split SPI write into two instea…
…d of concat. Add multibyte address test.
  • Loading branch information
FoamyGuy committed Sep 30, 2025
commit 262e9895245ff4dfb846ca9eccba768550e62c08
35 changes: 17 additions & 18 deletions adafruit_register/register_accessor.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ def write_register(
self._pack_address_into_buffer(address)
self._shift_rw_cmd_bit_into_first_byte(0)
with self.spi_device as spi:
spi.write(self.address_buffer + buffer)
spi.write(self.address_buffer)
spi.write(buffer)


class I2CRegisterAccessor(RegisterAccessor):
Expand All @@ -121,8 +122,7 @@ def __init__(self, i2c_device: I2CDevice, address_width: int = 1, lsb_first=True
super().__init__(address_width, lsb_first)
self.i2c_device = i2c_device

# buffer that will hold address + data for write_then_readinto operations
# will grow as needed
# buffer that will hold address + data for write operations, will grow as needed
self._full_buffer = bytearray(address_width + 1)

def read_register(self, address: int, buffer: bytearray):
Expand All @@ -134,23 +134,10 @@ def read_register(self, address: int, buffer: bytearray):
Buffer must be long enough to be read all data sent by the device.
:return: None
"""
if self.address_width + len(buffer) > len(self._full_buffer):
self._full_buffer = bytearray(self.address_width + len(buffer))

self._pack_address_into_buffer(address)
for i in range(self.address_width):
self._full_buffer[i] = self.address_buffer[i]

with self.i2c_device as i2c:
i2c.write_then_readinto(
self._full_buffer,
self._full_buffer,
out_end=self.address_width,
in_start=self.address_width,
)
# copy data from _full_buffer into buffer
for i in range(len(buffer)):
buffer[i] = self._full_buffer[self.address_width + i]
i2c.write_then_readinto(self.address_buffer, buffer)

def write_register(self, address: int, buffer: bytearray):
"""
Expand All @@ -161,6 +148,18 @@ def write_register(self, address: int, buffer: bytearray):

:return: None
"""
# grow full buffer if needed
if self.address_width + len(buffer) > len(self._full_buffer):
self._full_buffer = bytearray(self.address_width + len(buffer))

# put address into full buffer
self._pack_address_into_buffer(address)
for i in range(self.address_width):
self._full_buffer[i] = self.address_buffer[i]

# put data into full buffer
for i, b in enumerate(buffer):
self._full_buffer[i + self.address_width] = b

with self.i2c_device as i2c:
i2c.write(self.address_buffer + buffer)
i2c.write(self._full_buffer)
42 changes: 42 additions & 0 deletions examples/register_accessor_multibyte_address_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
# SPDX-License-Identifier: MIT
"""
Verify functionality of multibyte address registers.

Rrequires OV5640 camera connected.
Default pins are for RPi Pico + Adafruit PiCowbell Camera Breakout
"""

import board
import busio
import digitalio
from adafruit_bus_device.i2c_device import I2CDevice

from adafruit_register.register_accessor import I2CRegisterAccessor
from adafruit_register.register_bits import ROBits

I2C_ADDRESS = 0x3C
REG_CHIP_ID_HIGH = 0x300A


class OV5640Tester:
chip_id = ROBits(16, REG_CHIP_ID_HIGH, 0, register_width=2, lsb_first=False)

def __init__(self, i2c):
try:
i2c_device = I2CDevice(i2c, I2C_ADDRESS)
self.register_accessor = I2CRegisterAccessor(
i2c_device, address_width=2, lsb_first=False
)
except ValueError:
raise ValueError(f"No I2C device found.")


if __name__ == "__main__":
print("construct bus")
i2c = busio.I2C(board.GP5, board.GP4)
print("construct camera")
reset = digitalio.DigitalInOut(board.GP14)

ov5640 = OV5640Tester(i2c)
print(hex(ov5640.chip_id))