tests/extmod: Add machine_spi_rate test.
Based on machine_i2s_rate, allows testing basic SPI functionality and timings. Implemented and confirmed working for rp2, esp32, and pyboard. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
This commit is contained in:
parent
a4b3825bd4
commit
1e98c4cb75
152
tests/extmod/machine_spi_rate.py
Normal file
152
tests/extmod/machine_spi_rate.py
Normal file
@ -0,0 +1,152 @@
|
||||
# Test machine.SPI data transfer rates
|
||||
import sys
|
||||
|
||||
|
||||
try:
|
||||
import time
|
||||
from machine import Pin, SPI
|
||||
except ImportError:
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
MAX_DELTA_MS = 8
|
||||
|
||||
# Configure pins based on the port/board details.
|
||||
# Values are tuples of (spi_id, sck, mosi, miso)
|
||||
if "pyboard" in sys.platform:
|
||||
spi_instances = (
|
||||
(1, None, None, None), # "explicit choice of sck/mosi/miso is not implemented"
|
||||
(2, None, None, None),
|
||||
)
|
||||
elif "rp2" in sys.platform:
|
||||
spi_instances = ((0, Pin(18), Pin(19), Pin(16)),)
|
||||
elif "esp32" in sys.platform:
|
||||
spi_instances = [
|
||||
(1, Pin(18), Pin(19), Pin(21)),
|
||||
]
|
||||
if "ESP32C3" not in str(sys.implementation):
|
||||
spi_instances.append((2, Pin(18), Pin(19), Pin(21)))
|
||||
else:
|
||||
print("Please add support for this test on this platform.")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def get_real_baudrate(spi):
|
||||
# Return the 'real' baudrate for a SPI object, from parsing 'print' output
|
||||
# i.e.
|
||||
# SPI(id=1, baudrate=500000, polarity=0, phase=0, bits=8, firstbit=0, sck=14, mosi=13, miso=12)
|
||||
#
|
||||
# Note the 'real' rate may be quite different to the requested rate, i.e.
|
||||
# on ports where the SPI hardware only supports power of 2 clock dividers.
|
||||
#
|
||||
# Implementation is somewhat fiddly and inefficient to avoid dependency on
|
||||
# 're' module,
|
||||
s = str(spi)
|
||||
s = s.split("baudrate=")[1].split(",")[0]
|
||||
return int(s)
|
||||
|
||||
|
||||
def test_instances():
|
||||
print_results = True
|
||||
for spi_id, sck, mosi, miso in spi_instances:
|
||||
for baudrate in (
|
||||
100_000,
|
||||
250_000,
|
||||
800_000,
|
||||
1_000_000,
|
||||
2_000_000,
|
||||
4_000_000,
|
||||
8_000_000,
|
||||
):
|
||||
test_spi(
|
||||
spi_id,
|
||||
sck,
|
||||
mosi,
|
||||
miso,
|
||||
baudrate,
|
||||
0,
|
||||
0,
|
||||
print_results,
|
||||
)
|
||||
|
||||
for baudrate in (100_000, 4_000_000):
|
||||
# Test the other polarity and phase settings
|
||||
for polarity, phase in ((0, 1), (1, 0), (1, 1)):
|
||||
test_spi(
|
||||
spi_id,
|
||||
sck,
|
||||
mosi,
|
||||
miso,
|
||||
baudrate,
|
||||
polarity,
|
||||
phase,
|
||||
print_results,
|
||||
)
|
||||
|
||||
# Ensure the same test output regardless of how many SPI instances are tested
|
||||
print_results = False
|
||||
|
||||
|
||||
wr_short = b"abcdefghijklmnop" * 10
|
||||
rd_short = bytearray(len(wr_short))
|
||||
|
||||
wr_long = wr_short * 20
|
||||
rd_long = bytearray(len(wr_long))
|
||||
|
||||
|
||||
def test_spi(spi_id, sck, mosi, miso, baudrate, polarity, phase, print_results):
|
||||
if sck:
|
||||
s = SPI(
|
||||
spi_id,
|
||||
sck=sck,
|
||||
mosi=mosi,
|
||||
miso=miso,
|
||||
baudrate=baudrate,
|
||||
polarity=polarity,
|
||||
phase=phase,
|
||||
)
|
||||
else:
|
||||
s = SPI(spi_id, baudrate=baudrate, polarity=polarity, phase=phase)
|
||||
|
||||
# to keep the test runtime down, use shorter buffer for lower baud rate
|
||||
wr_buf = wr_long if baudrate > 500_000 else wr_short
|
||||
rd_buf = rd_long if baudrate > 500_000 else rd_short
|
||||
|
||||
real_baudrate = get_real_baudrate(s)
|
||||
assert real_baudrate
|
||||
transfer_time_ms = len(wr_buf) * 8 * 1000 // real_baudrate
|
||||
|
||||
def test_write_readinto():
|
||||
s.write_readinto(wr_buf, rd_buf)
|
||||
|
||||
def test_write():
|
||||
s.write(wr_buf)
|
||||
|
||||
def test_readinto():
|
||||
s.readinto(rd_buf)
|
||||
|
||||
for test_func, name in (
|
||||
(test_write_readinto, "write_readinto"),
|
||||
(test_write, "write"),
|
||||
(test_readinto, "readinto"),
|
||||
):
|
||||
t0 = time.ticks_ms()
|
||||
test_func()
|
||||
transfer_time = time.ticks_diff(time.ticks_ms(), t0)
|
||||
t_delta = abs(transfer_time - transfer_time_ms)
|
||||
t_ok = t_delta < MAX_DELTA_MS
|
||||
|
||||
if print_results or not t_ok:
|
||||
print(
|
||||
None if print_results else spi_id,
|
||||
baudrate,
|
||||
polarity,
|
||||
phase,
|
||||
name,
|
||||
t_ok or t_delta,
|
||||
)
|
||||
|
||||
s.deinit()
|
||||
|
||||
|
||||
test_instances()
|
||||
39
tests/extmod/machine_spi_rate.py.exp
Normal file
39
tests/extmod/machine_spi_rate.py.exp
Normal file
@ -0,0 +1,39 @@
|
||||
None 100000 0 0 write_readinto True
|
||||
None 100000 0 0 write True
|
||||
None 100000 0 0 readinto True
|
||||
None 250000 0 0 write_readinto True
|
||||
None 250000 0 0 write True
|
||||
None 250000 0 0 readinto True
|
||||
None 800000 0 0 write_readinto True
|
||||
None 800000 0 0 write True
|
||||
None 800000 0 0 readinto True
|
||||
None 1000000 0 0 write_readinto True
|
||||
None 1000000 0 0 write True
|
||||
None 1000000 0 0 readinto True
|
||||
None 2000000 0 0 write_readinto True
|
||||
None 2000000 0 0 write True
|
||||
None 2000000 0 0 readinto True
|
||||
None 4000000 0 0 write_readinto True
|
||||
None 4000000 0 0 write True
|
||||
None 4000000 0 0 readinto True
|
||||
None 8000000 0 0 write_readinto True
|
||||
None 8000000 0 0 write True
|
||||
None 8000000 0 0 readinto True
|
||||
None 100000 0 1 write_readinto True
|
||||
None 100000 0 1 write True
|
||||
None 100000 0 1 readinto True
|
||||
None 100000 1 0 write_readinto True
|
||||
None 100000 1 0 write True
|
||||
None 100000 1 0 readinto True
|
||||
None 100000 1 1 write_readinto True
|
||||
None 100000 1 1 write True
|
||||
None 100000 1 1 readinto True
|
||||
None 4000000 0 1 write_readinto True
|
||||
None 4000000 0 1 write True
|
||||
None 4000000 0 1 readinto True
|
||||
None 4000000 1 0 write_readinto True
|
||||
None 4000000 1 0 write True
|
||||
None 4000000 1 0 readinto True
|
||||
None 4000000 1 1 write_readinto True
|
||||
None 4000000 1 1 write True
|
||||
None 4000000 1 1 readinto True
|
||||
Loading…
x
Reference in New Issue
Block a user