Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eeprom stuff #82

Merged
merged 5 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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
Loading