2021-10-31 17:35:53 +00:00
|
|
|
# spiram_ test.py MicroPython test program for Adafruit SPIRAM device
|
|
|
|
# Adafruit https://www.adafruit.com/product/4677
|
|
|
|
|
|
|
|
|
|
|
|
# Released under the MIT License (MIT). See LICENSE.
|
|
|
|
# Copyright (c) 2021 Peter Hinch
|
|
|
|
|
|
|
|
import os
|
|
|
|
import time
|
|
|
|
from machine import SPI, Pin
|
|
|
|
from spiram import SPIRAM
|
|
|
|
|
|
|
|
cspins = (Pin(Pin.board.Y5, Pin.OUT, value=1), Pin(Pin.board.Y4, Pin.OUT, value=1))
|
|
|
|
|
|
|
|
# Return an RAM array. Adapt for platforms other than Pyboard.
|
|
|
|
def get_spiram():
|
2022-09-22 09:04:29 +00:00
|
|
|
if os.uname().machine.split(" ")[0][:4] == "PYBD":
|
2021-10-31 17:35:53 +00:00
|
|
|
Pin.board.EN_3V3.value(1)
|
|
|
|
time.sleep(0.1) # Allow decouplers to charge
|
|
|
|
ram = SPIRAM(SPI(2, baudrate=25_000_000), cspins)
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Instantiated RAM")
|
2021-10-31 17:35:53 +00:00
|
|
|
return ram
|
|
|
|
|
2022-09-22 09:04:29 +00:00
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
# Dumb file copy utility to help with managing FRAM contents at the REPL.
|
|
|
|
def cp(source, dest):
|
2022-09-22 09:04:29 +00:00
|
|
|
if dest.endswith("/"): # minimal way to allow
|
|
|
|
dest = "".join((dest, source.split("/")[-1])) # cp /sd/file /ram/
|
|
|
|
with open(source, "rb") as infile: # Caller should handle any OSError
|
|
|
|
with open(dest, "wb") as outfile: # e.g file not found
|
2021-10-31 17:35:53 +00:00
|
|
|
while True:
|
|
|
|
buf = infile.read(100)
|
|
|
|
outfile.write(buf)
|
|
|
|
if len(buf) < 100:
|
|
|
|
break
|
|
|
|
|
2022-09-22 09:04:29 +00:00
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
# ***** TEST OF DRIVER *****
|
|
|
|
def _testblock(eep, bs):
|
2022-09-22 09:04:29 +00:00
|
|
|
d0 = b"this >"
|
|
|
|
d1 = b"<is the boundary"
|
2021-10-31 17:35:53 +00:00
|
|
|
d2 = d0 + d1
|
2022-09-22 09:04:29 +00:00
|
|
|
garbage = b"xxxxxxxxxxxxxxxxxxx"
|
2021-10-31 17:35:53 +00:00
|
|
|
start = bs - len(d0)
|
|
|
|
end = start + len(garbage)
|
2022-09-22 09:04:29 +00:00
|
|
|
eep[start:end] = garbage
|
|
|
|
res = eep[start:end]
|
2021-10-31 17:35:53 +00:00
|
|
|
if res != garbage:
|
2022-09-22 09:04:29 +00:00
|
|
|
return "Block test fail 1:" + str(list(res))
|
2021-10-31 17:35:53 +00:00
|
|
|
end = start + len(d0)
|
2022-09-22 09:04:29 +00:00
|
|
|
eep[start:end] = d0
|
2021-10-31 17:35:53 +00:00
|
|
|
end = start + len(garbage)
|
2022-09-22 09:04:29 +00:00
|
|
|
res = eep[start:end]
|
|
|
|
if res != b"this >xxxxxxxxxxxxx":
|
|
|
|
return "Block test fail 2:" + str(list(res))
|
2021-10-31 17:35:53 +00:00
|
|
|
start = bs
|
|
|
|
end = bs + len(d1)
|
2022-09-22 09:04:29 +00:00
|
|
|
eep[start:end] = d1
|
2021-10-31 17:35:53 +00:00
|
|
|
start = bs - len(d0)
|
|
|
|
end = start + len(d2)
|
2022-09-22 09:04:29 +00:00
|
|
|
res = eep[start:end]
|
2021-10-31 17:35:53 +00:00
|
|
|
if res != d2:
|
2022-09-22 09:04:29 +00:00
|
|
|
return "Block test fail 3:" + str(list(res))
|
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
|
|
|
|
def test():
|
|
|
|
ram = get_spiram()
|
|
|
|
sa = 1000
|
|
|
|
for v in range(256):
|
|
|
|
ram[sa + v] = v
|
|
|
|
for v in range(256):
|
|
|
|
if ram[sa + v] != v:
|
2022-09-22 09:04:29 +00:00
|
|
|
print(
|
|
|
|
"Fail at address {} data {} should be {}".format(sa + v, ram[sa + v], v)
|
|
|
|
)
|
2021-10-31 17:35:53 +00:00
|
|
|
break
|
|
|
|
else:
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Test of byte addressing passed")
|
2021-10-31 17:35:53 +00:00
|
|
|
data = os.urandom(30)
|
|
|
|
sa = 2000
|
2022-09-22 09:04:29 +00:00
|
|
|
ram[sa : sa + 30] = data
|
|
|
|
if ram[sa : sa + 30] == data:
|
|
|
|
print("Test of slice readback passed")
|
2021-10-31 17:35:53 +00:00
|
|
|
# On SPIRAM the only meaningful block test is on a chip boundary.
|
|
|
|
block = ram._c_bytes
|
|
|
|
if ram._a_bytes > block:
|
|
|
|
res = _testblock(ram, block)
|
|
|
|
if res is None:
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Test chip boundary {} passed".format(block))
|
2021-10-31 17:35:53 +00:00
|
|
|
else:
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Test chip boundary {} fail".format(block))
|
2021-10-31 17:35:53 +00:00
|
|
|
print(res)
|
|
|
|
else:
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Test chip boundary skipped: only one chip!")
|
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
|
|
|
|
# ***** TEST OF FILESYSTEM MOUNT *****
|
|
|
|
def fstest():
|
|
|
|
ram = get_spiram()
|
|
|
|
os.VfsLfs2.mkfs(ram) # Format littlefs
|
|
|
|
try:
|
2022-09-22 09:04:29 +00:00
|
|
|
os.mount(ram, "/ram")
|
2021-10-31 17:35:53 +00:00
|
|
|
except OSError: # Already mounted
|
|
|
|
pass
|
2022-09-22 09:04:29 +00:00
|
|
|
print('Contents of "/": {}'.format(os.listdir("/")))
|
|
|
|
print('Contents of "/ram": {}'.format(os.listdir("/ram")))
|
|
|
|
print(os.statvfs("/ram"))
|
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
|
|
|
|
def cptest():
|
|
|
|
ram = get_spiram()
|
2022-09-22 09:04:29 +00:00
|
|
|
if "ram" in os.listdir("/"):
|
|
|
|
print("Device already mounted.")
|
2021-10-31 17:35:53 +00:00
|
|
|
else:
|
|
|
|
os.VfsLfs2.mkfs(ram) # Format littlefs
|
2022-09-22 09:04:29 +00:00
|
|
|
os.mount(ram, "/ram")
|
|
|
|
print("Formatted and mounted device.")
|
|
|
|
cp("/sd/spiram_test.py", "/ram/")
|
|
|
|
cp("/sd/spiram.py", "/ram/")
|
|
|
|
print('Contents of "/ram": {}'.format(os.listdir("/ram")))
|
|
|
|
print(os.statvfs("/ram"))
|
|
|
|
|
2021-10-31 17:35:53 +00:00
|
|
|
|
|
|
|
# ***** TEST OF HARDWARE *****
|
|
|
|
def full_test():
|
|
|
|
bsize = 2048
|
|
|
|
ram = get_spiram()
|
|
|
|
page = 0
|
|
|
|
for sa in range(0, len(ram), bsize):
|
|
|
|
data = os.urandom(bsize)
|
2022-09-22 09:04:29 +00:00
|
|
|
ram[sa : sa + bsize] = data
|
|
|
|
if ram[sa : sa + bsize] == data:
|
|
|
|
print("Page {} passed".format(page))
|
2021-10-31 17:35:53 +00:00
|
|
|
else:
|
2022-09-22 09:04:29 +00:00
|
|
|
print("Page {} readback failed.".format(page))
|
2021-10-31 17:35:53 +00:00
|
|
|
page += 1
|