tests/ports/rp2: Convert rp2.DMA test to a unittest.
This test is rather complicated and benefits from being a unittest. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
@@ -4,59 +4,86 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import machine
|
import machine
|
||||||
import rp2
|
import rp2
|
||||||
|
import unittest
|
||||||
|
|
||||||
is_rp2350 = "RP2350" in sys.implementation._machine
|
is_rp2350 = "RP2350" in sys.implementation._machine
|
||||||
|
|
||||||
src = bytes(i & 0xFF for i in range(16 * 1024))
|
SRC = bytes(i & 0xFF for i in range(16 * 1024))
|
||||||
|
|
||||||
print("# test basic usage")
|
|
||||||
|
|
||||||
dma = rp2.DMA()
|
class Test(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.dma = rp2.DMA()
|
||||||
|
|
||||||
# Test printing.
|
def tearDown(self):
|
||||||
print(dma)
|
self.dma.close()
|
||||||
|
|
||||||
# Test pack_ctrl/unpack_ctrl.
|
def test_printing(self):
|
||||||
|
dma = self.dma
|
||||||
|
self.assertEqual(str(dma), "DMA(0)")
|
||||||
|
|
||||||
|
def test_pack_unpack_ctrl(self):
|
||||||
|
dma = self.dma
|
||||||
ctrl_dict = rp2.DMA.unpack_ctrl(dma.pack_ctrl())
|
ctrl_dict = rp2.DMA.unpack_ctrl(dma.pack_ctrl())
|
||||||
if is_rp2350:
|
if is_rp2350:
|
||||||
for entry in ("inc_read_rev", "inc_write_rev"):
|
self.assertEqual(len(ctrl_dict), 18)
|
||||||
assert entry in ctrl_dict
|
self.assertTrue("inc_read_rev" in ctrl_dict)
|
||||||
del ctrl_dict[entry]
|
self.assertTrue("inc_write_rev" in ctrl_dict)
|
||||||
for key, value in sorted(ctrl_dict.items()):
|
else:
|
||||||
print(key, value)
|
self.assertEqual(len(ctrl_dict), 16)
|
||||||
|
self.assertEqual(ctrl_dict["ahb_err"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["bswap"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["busy"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["chain_to"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["enable"], 1)
|
||||||
|
self.assertEqual(ctrl_dict["high_pri"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["inc_read"], 1)
|
||||||
|
self.assertEqual(ctrl_dict["inc_write"], 1)
|
||||||
|
self.assertEqual(ctrl_dict["irq_quiet"], 1)
|
||||||
|
self.assertEqual(ctrl_dict["read_err"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["ring_sel"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["ring_size"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["size"], 2)
|
||||||
|
self.assertEqual(ctrl_dict["sniff_en"], 0)
|
||||||
|
self.assertEqual(ctrl_dict["treq_sel"], 63)
|
||||||
|
self.assertEqual(ctrl_dict["write_err"], 0)
|
||||||
|
|
||||||
# Test register access.
|
def test_register_access(self):
|
||||||
|
dma = self.dma
|
||||||
dma.read = 0
|
dma.read = 0
|
||||||
dma.write = 0
|
dma.write = 0
|
||||||
dma.count = 0
|
dma.count = 0
|
||||||
dma.ctrl = dma.pack_ctrl()
|
dma.ctrl = dma.pack_ctrl()
|
||||||
print(dma.read, dma.write, dma.count, dma.ctrl & 0x01F, dma.channel, dma.registers)
|
self.assertEqual(dma.read, 0)
|
||||||
|
self.assertEqual(dma.write, 0)
|
||||||
|
self.assertEqual(dma.count, 0)
|
||||||
|
self.assertEqual(dma.ctrl & 0x01F, 25)
|
||||||
|
self.assertEqual(dma.channel, 0)
|
||||||
|
self.assertIsInstance(dma.registers, memoryview)
|
||||||
|
|
||||||
|
def test_close(self):
|
||||||
|
dma = self.dma
|
||||||
dma.close()
|
dma.close()
|
||||||
|
|
||||||
# Test closing when already closed.
|
# Test closing when already closed.
|
||||||
dma.close()
|
dma.close()
|
||||||
|
|
||||||
# Test using when closed.
|
# Test using when closed.
|
||||||
try:
|
with self.assertRaises(ValueError):
|
||||||
dma.active()
|
dma.active()
|
||||||
assert False
|
|
||||||
except ValueError:
|
|
||||||
print("ValueError")
|
|
||||||
|
|
||||||
# Test simple memory copy.
|
def test_simple_memory_copy(self):
|
||||||
print("# test memory copy")
|
dma = self.dma
|
||||||
dest = bytearray(1024)
|
dest = bytearray(1024)
|
||||||
dma = rp2.DMA()
|
dma.config(read=SRC, write=dest, count=len(dest) // 4, ctrl=dma.pack_ctrl(), trigger=False)
|
||||||
dma.config(read=src, write=dest, count=len(dest) // 4, ctrl=dma.pack_ctrl(), trigger=False)
|
self.assertFalse(any(dest))
|
||||||
print(not any(dest))
|
|
||||||
dma.active(True)
|
dma.active(True)
|
||||||
while dma.active():
|
while dma.active():
|
||||||
pass
|
pass
|
||||||
print(dest[:8], dest[-8:])
|
self.assertEqual(dest[:8], SRC[:8])
|
||||||
dma.close()
|
self.assertEqual(dest[-8:], SRC[-8:])
|
||||||
|
|
||||||
|
def test_time_taken_for_large_memory_copy(self):
|
||||||
# Test time taken for a large memory copy.
|
|
||||||
def run_and_time_dma(dma):
|
def run_and_time_dma(dma):
|
||||||
ticks_us = time.ticks_us
|
ticks_us = time.ticks_us
|
||||||
irq_state = machine.disable_irq()
|
irq_state = machine.disable_irq()
|
||||||
@@ -68,39 +95,51 @@ def run_and_time_dma(dma):
|
|||||||
machine.enable_irq(irq_state)
|
machine.enable_irq(irq_state)
|
||||||
return time.ticks_diff(t1, t0)
|
return time.ticks_diff(t1, t0)
|
||||||
|
|
||||||
|
dma = self.dma
|
||||||
print("# test timing")
|
|
||||||
dest = bytearray(16 * 1024)
|
dest = bytearray(16 * 1024)
|
||||||
dma = rp2.DMA()
|
dma.read = SRC
|
||||||
dma.read = src
|
|
||||||
dma.write = dest
|
dma.write = dest
|
||||||
dma.count = len(dest) // 4
|
dma.count = len(dest) // 4
|
||||||
dma.ctrl = dma.pack_ctrl()
|
dma.ctrl = dma.pack_ctrl()
|
||||||
dt = run_and_time_dma(dma)
|
dt = run_and_time_dma(dma)
|
||||||
expected_dt_range = range(40, 70) if is_rp2350 else range(70, 125)
|
expected_dt_range = range(40, 70) if is_rp2350 else range(70, 125)
|
||||||
print(dt in expected_dt_range)
|
self.assertIn(dt, expected_dt_range)
|
||||||
print(dest[:8], dest[-8:])
|
self.assertEqual(dest[:8], SRC[:8])
|
||||||
dma.close()
|
self.assertEqual(dest[-8:], SRC[-8:])
|
||||||
|
|
||||||
# Test using .config(trigger=True).
|
def test_config_trigger(self):
|
||||||
print("# test immediate trigger")
|
# Test using .config(trigger=True) to start DMA immediately.
|
||||||
|
dma = self.dma
|
||||||
dest = bytearray(1024)
|
dest = bytearray(1024)
|
||||||
dma = rp2.DMA()
|
dma.config(read=SRC, write=dest, count=len(dest) // 4, ctrl=dma.pack_ctrl(), trigger=True)
|
||||||
dma.config(read=src, write=dest, count=len(dest) // 4, ctrl=dma.pack_ctrl(), trigger=True)
|
|
||||||
while dma.active():
|
while dma.active():
|
||||||
pass
|
pass
|
||||||
print(dest[:8], dest[-8:])
|
self.assertEqual(dest[:8], SRC[:8])
|
||||||
dma.close()
|
self.assertEqual(dest[-8:], SRC[-8:])
|
||||||
|
|
||||||
# Test the DMA.irq() method.
|
def test_irq(self):
|
||||||
print("# test irq")
|
def callback(dma):
|
||||||
|
nonlocal irq_flags
|
||||||
|
print("irq fired")
|
||||||
|
irq_flags = dma.irq().flags()
|
||||||
|
|
||||||
|
dma = self.dma
|
||||||
|
irq_flags = None
|
||||||
dest = bytearray(1024)
|
dest = bytearray(1024)
|
||||||
dma = rp2.DMA()
|
dma.irq(callback)
|
||||||
dma.irq(lambda dma: print("irq fired", dma.irq().flags()))
|
|
||||||
dma.config(
|
dma.config(
|
||||||
read=src, write=dest, count=len(dest) // 4, ctrl=dma.pack_ctrl(irq_quiet=0), trigger=True
|
read=SRC,
|
||||||
|
write=dest,
|
||||||
|
count=len(dest) // 4,
|
||||||
|
ctrl=dma.pack_ctrl(irq_quiet=0),
|
||||||
|
trigger=True,
|
||||||
)
|
)
|
||||||
while dma.active():
|
while dma.active():
|
||||||
pass
|
pass
|
||||||
print(dest[:8], dest[-8:])
|
self.assertEqual(irq_flags, 1)
|
||||||
dma.close()
|
self.assertEqual(dest[:8], SRC[:8])
|
||||||
|
self.assertEqual(dest[-8:], SRC[-8:])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
# test basic usage
|
|
||||||
DMA(0)
|
|
||||||
ahb_err 0
|
|
||||||
bswap 0
|
|
||||||
busy 0
|
|
||||||
chain_to 0
|
|
||||||
enable 1
|
|
||||||
high_pri 0
|
|
||||||
inc_read 1
|
|
||||||
inc_write 1
|
|
||||||
irq_quiet 1
|
|
||||||
read_err 0
|
|
||||||
ring_sel 0
|
|
||||||
ring_size 0
|
|
||||||
size 2
|
|
||||||
sniff_en 0
|
|
||||||
treq_sel 63
|
|
||||||
write_err 0
|
|
||||||
0 0 0 25 0 <memoryview>
|
|
||||||
ValueError
|
|
||||||
# test memory copy
|
|
||||||
True
|
|
||||||
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07') bytearray(b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff')
|
|
||||||
# test timing
|
|
||||||
True
|
|
||||||
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07') bytearray(b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff')
|
|
||||||
# test immediate trigger
|
|
||||||
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07') bytearray(b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff')
|
|
||||||
# test irq
|
|
||||||
irq fired 1
|
|
||||||
bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07') bytearray(b'\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff')
|
|
||||||
Reference in New Issue
Block a user