Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/eeprom_stuff' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewWilkes committed Jun 17, 2024
2 parents a6c88e4 + baad6b2 commit 9876c54
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 31 deletions.
12 changes: 9 additions & 3 deletions modules/scripts/mount_hexpansions.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
from machine import I2C
from system.hexpansion.util import read_hexpansion_header, get_hexpansion_block_devices
from system.hexpansion.util import read_hexpansion_header, get_hexpansion_block_devices, detect_eeprom_addr
import vfs
import os

for port in range(1, 7):
print(f"Attempting to mount hexpansion in port: {port}")
i2c = I2C(port)

header = read_hexpansion_header(i2c)
addr, addr_len = detect_eeprom_addr(i2c)
if addr is None:
continue
header = read_hexpansion_header(i2c, eeprom_addr=addr, addr_len=addr_len)
if header is None:
continue

try:
eep, partition = get_hexpansion_block_devices(i2c, header)
eep, partition = get_hexpansion_block_devices(i2c, header, addr_len=addr_len)
except Exception as e:
print(f"Failed to get block devices for hexpansion {port}: {e}")
continue
Expand All @@ -25,3 +29,5 @@
continue

print(f"Mounted hexpansion {port} at {mountpoint}")
print(os.statvfs(mountpoint))
print(os.listdir(mountpoint))
27 changes: 19 additions & 8 deletions modules/scripts/prepare_eeprom.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,35 @@
i2c = I2C(port)

# autodetect eeprom address
addr = detect_eeprom_addr(i2c)
addr, addr_len = detect_eeprom_addr(i2c)
print(f"Detected eeprom at {hex(addr)}")

# Fill in your desired header info here:
header = HexpansionHeader(
# use this one for the M24C16:
header_m24c16 = HexpansionHeader(
manifest_version="2024",
fs_offset=32,
eeprom_page_size=16,
eeprom_total_size=1024 * (16 // 8) // 8,
eeprom_total_size=1024 * (16 // 8),
vid=0xCA75,
pid=0x1337,
unique_id=0,
friendly_name="M24C16"
)
# use this template for the ZD24C64A
header_zd24c64 = HexpansionHeader(
manifest_version="2024",
fs_offset=32,
eeprom_page_size=32,
eeprom_total_size=1024 * (64 // 8),
vid=0xCA75,
pid=0x1337,
unique_id=0x0,
friendly_name="Flopagon",
friendly_name="ZD24C64A",
)

# Determine amount of bytes in internal address
addr_len = 2 if header.eeprom_total_size > 256 else 1
print(f"Using {addr_len} bytes for eeprom internal address")
# pick which one to use here
header = header_m24c16

# Write and read back header
write_header(
Expand All @@ -43,7 +54,7 @@
raise RuntimeError("Failed to read back hexpansion header")

# Get block devices
eep, partition = get_hexpansion_block_devices(i2c, header, addr)
eep, partition = get_hexpansion_block_devices(i2c, header, addr, addr_len=addr_len)

# Format
vfs.VfsLfs2.mkfs(partition)
Expand Down
6 changes: 3 additions & 3 deletions modules/system/hexpansion/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,13 @@ async def handle_hexpansion_insertion(self, event):
i2c = I2C(event.port)

# Autodetect eeprom addr
addr = detect_eeprom_addr(i2c)
addr, addr_len = detect_eeprom_addr(i2c)
if addr is None:
print("Scan found no eeproms")
return

# Do we have a header?
header = read_hexpansion_header(i2c, addr)
header = read_hexpansion_header(i2c, addr, addr_len=addr_len)
if header is None:
return

Expand All @@ -196,7 +196,7 @@ async def handle_hexpansion_insertion(self, event):
# Try creating block devices, one for the whole eeprom,
# one for the partition with the filesystem on it
try:
eep, partition = get_hexpansion_block_devices(i2c, header, addr)
eep, partition = get_hexpansion_block_devices(i2c, header, addr, addr_len=addr_len)
except RuntimeError as e:
print(f"Could not initialize eeprom: {e}")
eep = None
Expand Down
12 changes: 7 additions & 5 deletions modules/system/hexpansion/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ def from_bytes(cls, buf, validate_checksum=True):
def write_header(port, header, addr=0x50, addr_len=2, page_size=32):
i2c = I2C(port)

addr_bytes = [0] * addr_len
i2c.writeto(addr, bytes(addr_bytes))
if addr_len == 2:
addr_pack = ">H"
else:
addr_pack = ">B"

# We can't write more bytes than the page size in one transaction, so chunk the bytes if necessary:
header_bytes = header.to_bytes()
Expand All @@ -107,10 +109,10 @@ def write_header(port, header, addr=0x50, addr_len=2, page_size=32):
]

for idx, chunk in enumerate(header_chunks):
write_addr = bytes([idx * page_size])
print(f"Writing {len(chunk)} bytes at {write_addr}:", chunk)
write_addr = struct.pack(addr_pack, idx * page_size)
print(f"Writing {len(chunk)} bytes at {idx * page_size}:", chunk)

i2c.writeto(addr, bytes([idx * page_size]) + chunk)
i2c.writeto(addr, write_addr + chunk)

# Poll ACK
while True:
Expand Down
30 changes: 18 additions & 12 deletions modules/system/hexpansion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
def detect_eeprom_addr(i2c):
devices = i2c.scan()
if 0x57 in devices and 0x50 not in devices:
return 0x57
return (0x57, 2)
if 0x57 in devices and 0x56 in devices and 0x55 in devices and 0x54 in devices and 0x53 in devices and 0x52 in devices and 0x51 in devices and 0x50 in devices:
return (0x50, 1)
if 0x50 in devices:
return 0x50
return None
return (0x50, 2)
return (None, None)


def read_hexpansion_header(
Expand All @@ -37,12 +39,8 @@ def read_hexpansion_header(

if set_read_addr:
addr_bytes = [0] * addr_len
try:
i2c.writeto(eeprom_addr, bytes(addr_bytes))
except OSError:
# Potentially write protected, and only one address byte
i2c.writeto(eeprom_addr, bytes([0]))

i2c.writeto(eeprom_addr, bytes(addr_bytes))

header_bytes = i2c.readfrom(eeprom_addr, 32)

try:
Expand All @@ -54,12 +52,20 @@ def read_hexpansion_header(
return header


def get_hexpansion_block_devices(i2c, header, addr=0x50):
def get_hexpansion_block_devices(i2c, header, addr=0x50, addr_len=2):
if header.eeprom_total_size > 2 ** (8 * addr_len):
chip_size = 2 ** (8 * addr_len)
else:
chip_size = header.eeprom_total_size
if header.eeprom_total_size >= 8192:
block_size = 9 # 512 byte blocks for big EEPROMs
else:
block_size = 6 # 64 byte blocks on small EEPROMs
eep = EEPROM(
i2c=i2c,
chip_size=header.eeprom_total_size,
chip_size=chip_size,
page_size=header.eeprom_page_size,
addr=addr,
block_size=block_size
)
partition = EEPROMPartition(
eep=eep,
Expand Down

0 comments on commit 9876c54

Please sign in to comment.