Skip to content

Commit 5861e93

Browse files
committed
EEPROM: SPI and I2C full_test now more rigorous.
1 parent 3b2e253 commit 5861e93

File tree

2 files changed

+108
-36
lines changed

2 files changed

+108
-36
lines changed

eeprom/i2c/eep_i2c.py

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,42 @@
55

66
import uos
77
import time
8-
from machine import I2C, Pin
8+
from machine import I2C, Pin, SoftI2C
99
from eeprom_i2c import EEPROM, T24C512
1010

1111
# Return an EEPROM array. Adapt for platforms other than Pyboard or chips
1212
# smaller than 64KiB.
1313
def get_eep():
14+
# Special code for Pyboard D: enable 3.3V output
1415
if uos.uname().machine.split(" ")[0][:4] == "PYBD":
1516
Pin.board.EN_3V3.value(1)
1617
time.sleep(0.1) # Allow decouplers to charge
17-
eep = EEPROM(I2C(2), T24C512)
18+
19+
if uos.uname().sysname == "esp8266":
20+
eep = EEPROM(SoftI2C(scl=Pin(13, Pin.OPEN_DRAIN), sda=Pin(12, Pin.OPEN_DRAIN)), T24C512)
21+
else:
22+
eep = EEPROM(I2C(2), T24C512) # Pyboard D or 1.x
1823
print("Instantiated EEPROM")
1924
return eep
2025

2126

27+
# Yield pseudorandom bytes (random module not available on all ports)
28+
def psrand8(x=0x3FBA2):
29+
while True:
30+
x ^= (x & 0x1FFFF) << 13
31+
x ^= x >> 17
32+
x ^= (x & 0x1FFFFFF) << 5
33+
yield x & 0xFF
34+
35+
36+
# Given a source of pseudorandom bytes yield pseudorandom 256 byte buffer.
37+
def psrand256(rand, ba=bytearray(256)):
38+
while True:
39+
for z in range(256):
40+
ba[z] = next(rand)
41+
yield ba
42+
43+
2244
# Dumb file copy utility to help with managing EEPROM contents at the REPL.
2345
def cp(source, dest):
2446
if dest.endswith("/"): # minimal way to allow
@@ -144,28 +166,39 @@ def cptest(eep=None): # Assumes pre-existing filesystem of either type
144166
print("Fail mounting device. Have you formatted it?")
145167
return
146168
print("Mounted device.")
147-
cp(__file__, "/eeprom/")
148-
# We may have the source file or a precompiled binary (*.mpy)
149-
cp(__file__.replace("eep", "eeprom"), "/eeprom/")
150-
print('Contents of "/eeprom": {}'.format(uos.listdir("/eeprom")))
151-
print(uos.statvfs("/eeprom"))
169+
try:
170+
cp(__file__, "/eeprom/")
171+
# We may have the source file or a precompiled binary (*.mpy)
172+
cp(__file__.replace("eep", "eeprom"), "/eeprom/")
173+
print('Contents of "/eeprom": {}'.format(uos.listdir("/eeprom")))
174+
print(uos.statvfs("/eeprom"))
175+
except NameError:
176+
print("Test cannot be performed by this MicroPython port. Consider using upysh.")
152177

153178

154179
# ***** TEST OF HARDWARE *****
155-
def full_test(eep=None, block_size=256):
180+
# Write pseudorandom data to entire array, then read back. Fairly rigorous test.
181+
def full_test(eep=None):
156182
eep = eep if eep else get_eep()
157-
print(f"Testing with {block_size}byte blocks of random data...")
158-
block = 0
159-
for sa in range(0, len(eep), block_size):
160-
data = uos.urandom(block_size)
161-
eep[sa : sa + block_size] = data
162-
if eep[sa : sa + block_size] == data:
163-
print(f"Block {block} passed\r", end="")
183+
print("Testing with 256 byte blocks of random data...")
184+
r = psrand8() # Instantiate random byte generator
185+
ps = psrand256(r) # Random 256 byte blocks
186+
for sa in range(0, len(eep), 256):
187+
ea = sa + 256
188+
eep[sa:ea] = next(ps)
189+
print(f"Address {sa}..{ea} written\r", end="")
190+
print()
191+
r = psrand8() # Instantiate new random byte generator with same seed
192+
ps = psrand256(r) # Random 256 byte blocks
193+
for sa in range(0, len(eep), 256):
194+
ea = sa + 256
195+
if eep[sa:ea] == next(ps):
196+
print(f"Address {sa}..{ea} readback passed\r", end="")
164197
else:
165-
print(f"Block {block} readback failed.")
166-
block += 1
198+
print(f"Address {sa}..{ea} readback failed.")
167199
print()
168200

201+
169202
def help():
170203
st = """Available commands:
171204
help() Print this text.
@@ -180,4 +213,5 @@ def help():
180213
"""
181214
print(st)
182215

216+
183217
help()

eeprom/spi/eep_spi.py

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,59 @@
11
# eep_spi.py MicroPython test program for Microchip SPI EEPROM devices.
22

33
# Released under the MIT License (MIT). See LICENSE.
4-
# Copyright (c) 2019-2022 Peter Hinch
4+
# Copyright (c) 2019-2024 Peter Hinch
55

66
import uos
77
import time
8-
from machine import SPI, Pin
8+
from machine import SPI, Pin, SoftSPI
99
from eeprom_spi import EEPROM
1010

11+
ESP8266 = uos.uname().sysname == "esp8266"
1112
# Add extra pins if using multiple chips
12-
cspins = (Pin(Pin.board.Y5, Pin.OUT, value=1), Pin(Pin.board.Y4, Pin.OUT, value=1))
13+
if ESP8266:
14+
cspins = (Pin(5, Pin.OUT, value=1), Pin(14, Pin.OUT, value=1))
15+
else:
16+
cspins = (Pin(Pin.board.Y5, Pin.OUT, value=1), Pin(Pin.board.Y4, Pin.OUT, value=1))
1317

1418
# Return an EEPROM array. Adapt for platforms other than Pyboard.
1519
def get_eep(stm):
1620
if uos.uname().machine.split(" ")[0][:4] == "PYBD":
1721
Pin.board.EN_3V3.value(1)
1822
time.sleep(0.1) # Allow decouplers to charge
23+
1924
if stm:
20-
eep = EEPROM(SPI(2, baudrate=5_000_000), cspins, 256)
25+
if ESP8266:
26+
spi = SoftSPI(baudrate=5_000_000, sck=Pin(4), miso=Pin(0), mosi=Pin(2))
27+
else: # Pyboard
28+
spi = SPI(2, baudrate=5_000_000)
29+
eep = EEPROM(spi, cspins, 256)
2130
else:
22-
eep = EEPROM(SPI(2, baudrate=20_000_000), cspins, 128)
31+
if ESP8266:
32+
spi = SoftSPI(baudrate=20_000_000, sck=Pin(4), miso=Pin(0), mosi=Pin(2))
33+
else:
34+
spi = SPI(2, baudrate=20_000_000)
35+
eep = EEPROM(spi, cspins, 128)
2336
print("Instantiated EEPROM")
2437
return eep
2538

2639

40+
# Yield pseudorandom bytes (random module not available on all ports)
41+
def psrand8(x=0x3FBA2):
42+
while True:
43+
x ^= (x & 0x1FFFF) << 13
44+
x ^= x >> 17
45+
x ^= (x & 0x1FFFFFF) << 5
46+
yield x & 0xFF
47+
48+
49+
# Given a source of pseudorandom bytes yield pseudorandom 256 byte buffer.
50+
def psrand256(rand, ba=bytearray(256)):
51+
while True:
52+
for z in range(256):
53+
ba[z] = next(rand)
54+
yield ba
55+
56+
2757
# Dumb file copy utility to help with managing EEPROM contents at the REPL.
2858
def cp(source, dest):
2959
if dest.endswith("/"): # minimal way to allow
@@ -149,27 +179,35 @@ def cptest(stm=False): # Assumes pre-existing filesystem of either type
149179
print("Fail mounting device. Have you formatted it?")
150180
return
151181
print("Mounted device.")
152-
cp(__file__, "/eeprom/")
153-
# We may have the source file or a precompiled binary (*.mpy)
154-
cp(__file__.replace("eep", "eeprom"), "/eeprom/")
155-
print('Contents of "/eeprom": {}'.format(uos.listdir("/eeprom")))
156-
print(uos.statvfs("/eeprom"))
182+
try:
183+
cp(__file__, "/eeprom/")
184+
# We may have the source file or a precompiled binary (*.mpy)
185+
cp(__file__.replace("eep", "eeprom"), "/eeprom/")
186+
print('Contents of "/eeprom": {}'.format(uos.listdir("/eeprom")))
187+
print(uos.statvfs("/eeprom"))
188+
except NameError:
189+
print("Test cannot be performed by this MicroPython port. Consider using upysh.")
157190

158191

159192
# ***** TEST OF HARDWARE *****
160193
def full_test(stm=False):
161194
eep = get_eep(stm)
162-
block = 0
195+
print("Testing with 256 byte blocks of random data...")
196+
r = psrand8() # Instantiate random byte generator
197+
ps = psrand256(r) # Random 256 byte blocks
163198
for sa in range(0, len(eep), 256):
164-
data = uos.urandom(256)
165-
eep[sa : sa + 256] = data
166-
got = eep[sa : sa + 256]
167-
if got == data:
168-
print(f"Block {block} passed\r", end="")
199+
ea = sa + 256
200+
eep[sa:ea] = next(ps)
201+
print(f"Address {sa}..{ea} written\r", end="")
202+
print()
203+
r = psrand8() # Instantiate new random byte generator with same seed
204+
ps = psrand256(r) # Random 256 byte blocks
205+
for sa in range(0, len(eep), 256):
206+
ea = sa + 256
207+
if eep[sa:ea] == next(ps):
208+
print(f"Address {sa}..{ea} readback passed\r", end="")
169209
else:
170-
print(f"Block {block} readback failed.")
171-
break
172-
block += 1
210+
print(f"Address {sa}..{ea} readback failed.")
173211
print()
174212

175213

0 commit comments

Comments
 (0)