AT28C256-rpi-util/eeprom_sim.py
2023-10-26 19:01:14 +02:00

139 lines
3.8 KiB
Python

from time import time
from sys import argv
from time import sleep
from RPi.GPIO import IN, OUT
import RPi.GPIO as GPIO
from opcodes import opcodes_d
# EEPROM AT28C256 Pin names and RPi GPIO Pin Numbers
# b means bar = inverted
gpio_l = [2, 3, 4, 17, 27, 22, 10, 9, 11, 5, 6, 13, 19, 26]
gpio_r = [14, 15, 18, 23, 24, 25, 8, 7, 12, 16, 20, 21]
#
# Defining which 6502 pin goes to which GPIO pin
#
"""
IO = gpio_r[-8:] # 8 io pins
IO.reverse()
A = [13, 6, 5, 11, 9, 10, 22, 27,
17, 4, 3, 2,
23, 18, 15]
# OEb = 26 # Output Enable
RWb = 19 # Write Enable
CEb = 14 # Chip Enable is hooked up to A15 on the processor
PHI2 = 26
controls = [CEb, RWb, PHI2]
"""
A = [
27, 22, 10, 9, 11, 5, 6, 13, # A0-A7
4, 2, 18, 3, # A8-A11
23, 17, 15 # A12-A14
]
IO = [ 24, 25, 8, 7, 12, 16, 20, 21 ]
RWb = 19 # Write Enable
CEb = 14 # Chip Enable is hooked up to A15 on the processor
PHI2 = 26
controls = [CEb, RWb, PHI2]
# Address setup time
t_AS = 300e-9
# setup the pins
GPIO.setmode(GPIO.BCM)
for pin in controls:
GPIO.setup(pin, IN)
for pin in A:
GPIO.setup(pin, IN)
def setup_pins(IOdirection=OUT):
# OUT when writing and IN when reading
for pin in IO:
if IOdirection == OUT:
GPIO.setup(pin, IOdirection, initial=0)
elif IOdirection == IN:
GPIO.setup(pin, IOdirection)
# print("setup pins", IOdirection)
def print_pins():
for i in range(len(A)):
print(f"A{i} - {A[i]}")
for i in range(len(IO)):
print(f"IO{i} - {IO[i]}")
print(f"CEb - {CEb}")
print(f"RWb - {RWb}")
print(f"PHI2 - {PHI2}")
def get_8_bit(l: list):
for i in range(len(l)):
l[i] = format(l[i], f"08b") # get the 8-bit bin value
return l
def check_enable():
# assumes the EEPROM is only hooked up via CE. If CE is low, it will ouput data
if GPIO.input(CEb) == 0 and GPIO.input(RWb) == 1:
return True
return False
def decode_address():
ad_s = ""
for i in range(len(A)):
ad_s += str(GPIO.input(A[len(A)-1-i]))
return int(ad_s, 2)
def simulate(path, verbose=True):
with open(path, "rb") as file:
bindata = file.read()
data = []
for i in range(len(bindata)):
data.append(format(bindata[i], "08b"))
while True:
GPIO.cleanup(IO)
setup_pins(IN)
# address is set on falling edge
channel = GPIO.wait_for_edge(PHI2, GPIO.FALLING, timeout=1000) # allow for KeyboardInterrupts
if channel is None:
continue
# wait an address setup time, dependant on clock speed!
sleep(t_AS)
enable = check_enable()
address = decode_address()
# put the data on the bus
if enable:
setup_pins(OUT)
for i in range(8):
if data[address][i] == "0":
GPIO.output(IO[7-i], 0)
else:
GPIO.output(IO[7-i], 1)
# wait the output hold time
if verbose:
print(f"OUT|||{format(address + 0x8000, '015b')} - {data[address]}|||{format(address + 0x8000, '04x')} - {format(int(data[address], 2), '02x')}", end="")
if int(data[address], 2) in opcodes_d:
print(f" ||| {opcodes_d[int(data[address], 2)]}")
else:
print("")
elif verbose:
data_in = ""
for i in range(8):
data_in += str(GPIO.input(IO[7-i]))
print(f"IN |||{format(address, '016b')} - {data_in}|||{format(address, '04x')} - {format(int(data_in, 2), '02x')}")
if len(argv) > 1:
try:
simulate(argv[1])
except KeyboardInterrupt:
GPIO.cleanup()
else:
print("No filepath given. Printing Pin-Settings")
print_pins()
# if performing action from this script, put the code HERE:
GPIO.cleanup()