|
1 | 1 | # eep_spi.py MicroPython test program for Microchip SPI EEPROM devices. |
2 | 2 |
|
3 | 3 | # Released under the MIT License (MIT). See LICENSE. |
4 | | -# Copyright (c) 2019-2022 Peter Hinch |
| 4 | +# Copyright (c) 2019-2024 Peter Hinch |
5 | 5 |
|
6 | 6 | import uos |
7 | 7 | import time |
8 | | -from machine import SPI, Pin |
| 8 | +from machine import SPI, Pin, SoftSPI |
9 | 9 | from eeprom_spi import EEPROM |
10 | 10 |
|
| 11 | +ESP8266 = uos.uname().sysname == "esp8266" |
11 | 12 | # 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)) |
13 | 17 |
|
14 | 18 | # Return an EEPROM array. Adapt for platforms other than Pyboard. |
15 | 19 | def get_eep(stm): |
16 | 20 | if uos.uname().machine.split(" ")[0][:4] == "PYBD": |
17 | 21 | Pin.board.EN_3V3.value(1) |
18 | 22 | time.sleep(0.1) # Allow decouplers to charge |
| 23 | + |
19 | 24 | 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) |
21 | 30 | 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) |
23 | 36 | print("Instantiated EEPROM") |
24 | 37 | return eep |
25 | 38 |
|
26 | 39 |
|
| 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 | + |
27 | 57 | # Dumb file copy utility to help with managing EEPROM contents at the REPL. |
28 | 58 | def cp(source, dest): |
29 | 59 | if dest.endswith("/"): # minimal way to allow |
@@ -149,27 +179,35 @@ def cptest(stm=False): # Assumes pre-existing filesystem of either type |
149 | 179 | print("Fail mounting device. Have you formatted it?") |
150 | 180 | return |
151 | 181 | 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.") |
157 | 190 |
|
158 | 191 |
|
159 | 192 | # ***** TEST OF HARDWARE ***** |
160 | 193 | def full_test(stm=False): |
161 | 194 | 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 |
163 | 198 | 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="") |
169 | 209 | else: |
170 | | - print(f"Block {block} readback failed.") |
171 | | - break |
172 | | - block += 1 |
| 210 | + print(f"Address {sa}..{ea} readback failed.") |
173 | 211 | print() |
174 | 212 |
|
175 | 213 |
|
|
0 commit comments