mirror of
https://github.com/micropython/micropython.git
synced 2025-12-16 01:40:14 +01:00
tests/multi_extmod: Add I2CTarget multi tests.
These require two boards wired together, SCL-SCL and SDA-SDA. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
137
tests/multi_extmod/machine_i2c_target_irq.py
Normal file
137
tests/multi_extmod/machine_i2c_target_irq.py
Normal file
@@ -0,0 +1,137 @@
|
||||
# Test I2CTarget IRQs and clock stretching.
|
||||
#
|
||||
# Requires two instances with their SCL and SDA lines connected together.
|
||||
# Any combination of the below supported boards can be used.
|
||||
#
|
||||
# Notes:
|
||||
# - pull-up resistors may be needed
|
||||
# - alif use 1.8V signalling
|
||||
|
||||
import sys
|
||||
import time
|
||||
from machine import I2C, I2CTarget
|
||||
|
||||
if not hasattr(I2CTarget, "IRQ_ADDR_MATCH_READ"):
|
||||
print("SKIP")
|
||||
raise SystemExit
|
||||
|
||||
ADDR = 67
|
||||
clock_stretch_us = 200
|
||||
|
||||
# Configure pins based on the target.
|
||||
if sys.platform == "alif":
|
||||
i2c_args = (1,) # pins P3_7/P3_6
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "mimxrt":
|
||||
i2c_args = (0,) # pins 19/18 on Teensy 4.x
|
||||
i2c_kwargs = {}
|
||||
clock_stretch_us = 50 # mimxrt cannot delay too long in the IRQ handler
|
||||
elif sys.platform == "rp2":
|
||||
i2c_args = (0,)
|
||||
i2c_kwargs = {"scl": 9, "sda": 8}
|
||||
elif sys.platform == "pyboard":
|
||||
i2c_args = ("Y",)
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "samd":
|
||||
i2c_args = () # pins SCL/SDA
|
||||
i2c_kwargs = {}
|
||||
elif "zephyr-rpi_pico" in sys.implementation._machine:
|
||||
i2c_args = ("i2c1",) # on gpio7/gpio6
|
||||
i2c_kwargs = {}
|
||||
else:
|
||||
print("Please add support for this test on this platform.")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def simple_irq(i2c_target):
|
||||
flags = i2c_target.irq().flags()
|
||||
if flags & I2CTarget.IRQ_ADDR_MATCH_READ:
|
||||
print("IRQ_ADDR_MATCH_READ")
|
||||
if flags & I2CTarget.IRQ_ADDR_MATCH_WRITE:
|
||||
print("IRQ_ADDR_MATCH_WRITE")
|
||||
|
||||
# Force clock stretching.
|
||||
time.sleep_us(clock_stretch_us)
|
||||
|
||||
|
||||
class I2CTargetMemory:
|
||||
def __init__(self, i2c_target, mem):
|
||||
self.buf1 = bytearray(1)
|
||||
self.mem = mem
|
||||
self.memaddr = 0
|
||||
self.state = 0
|
||||
i2c_target.irq(
|
||||
self.irq,
|
||||
I2CTarget.IRQ_ADDR_MATCH_WRITE | I2CTarget.IRQ_READ_REQ | I2CTarget.IRQ_WRITE_REQ,
|
||||
hard=True,
|
||||
)
|
||||
|
||||
def irq(self, i2c_target):
|
||||
# Force clock stretching.
|
||||
time.sleep_us(clock_stretch_us)
|
||||
|
||||
flags = i2c_target.irq().flags()
|
||||
if flags & I2CTarget.IRQ_ADDR_MATCH_WRITE:
|
||||
self.state = 0
|
||||
if flags & I2CTarget.IRQ_READ_REQ:
|
||||
self.buf1[0] = self.mem[self.memaddr]
|
||||
self.memaddr += 1
|
||||
i2c_target.write(self.buf1)
|
||||
if flags & I2CTarget.IRQ_WRITE_REQ:
|
||||
i2c_target.readinto(self.buf1)
|
||||
if self.state == 0:
|
||||
self.state = 1
|
||||
self.memaddr = self.buf1[0]
|
||||
else:
|
||||
self.mem[self.memaddr] = self.buf1[0]
|
||||
self.memaddr += 1
|
||||
self.memaddr %= len(self.mem)
|
||||
|
||||
# Force clock stretching.
|
||||
time.sleep_us(clock_stretch_us)
|
||||
|
||||
|
||||
# I2C controller
|
||||
def instance0():
|
||||
i2c = I2C(*i2c_args, **i2c_kwargs)
|
||||
multitest.next()
|
||||
for iteration in range(2):
|
||||
print("controller iteration", iteration)
|
||||
multitest.wait("target stage 1")
|
||||
i2c.writeto_mem(ADDR, 2, "0123")
|
||||
multitest.broadcast("controller stage 2")
|
||||
multitest.wait("target stage 3")
|
||||
print(i2c.readfrom_mem(ADDR, 2, 4))
|
||||
multitest.broadcast("controller stage 4")
|
||||
print("done")
|
||||
|
||||
|
||||
# I2C target
|
||||
def instance1():
|
||||
multitest.next()
|
||||
|
||||
for iteration in range(2):
|
||||
print("target iteration", iteration)
|
||||
buf = bytearray(b"--------")
|
||||
if iteration == 0:
|
||||
# Use built-in memory capability of I2CTarget.
|
||||
i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR, mem=buf)
|
||||
i2c_target.irq(
|
||||
simple_irq,
|
||||
I2CTarget.IRQ_ADDR_MATCH_READ | I2CTarget.IRQ_ADDR_MATCH_WRITE,
|
||||
hard=True,
|
||||
)
|
||||
else:
|
||||
# Implement a memory device by hand.
|
||||
i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR)
|
||||
I2CTargetMemory(i2c_target, buf)
|
||||
|
||||
multitest.broadcast("target stage 1")
|
||||
multitest.wait("controller stage 2")
|
||||
print(buf)
|
||||
multitest.broadcast("target stage 3")
|
||||
multitest.wait("controller stage 4")
|
||||
|
||||
i2c_target.deinit()
|
||||
|
||||
print("done")
|
||||
15
tests/multi_extmod/machine_i2c_target_irq.py.exp
Normal file
15
tests/multi_extmod/machine_i2c_target_irq.py.exp
Normal file
@@ -0,0 +1,15 @@
|
||||
--- instance0 ---
|
||||
controller iteration 0
|
||||
b'0123'
|
||||
controller iteration 1
|
||||
b'0123'
|
||||
done
|
||||
--- instance1 ---
|
||||
target iteration 0
|
||||
IRQ_ADDR_MATCH_WRITE
|
||||
bytearray(b'--0123--')
|
||||
IRQ_ADDR_MATCH_WRITE
|
||||
IRQ_ADDR_MATCH_READ
|
||||
target iteration 1
|
||||
bytearray(b'--0123--')
|
||||
done
|
||||
79
tests/multi_extmod/machine_i2c_target_memory.py
Normal file
79
tests/multi_extmod/machine_i2c_target_memory.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# Test basic use of I2CTarget and a memory buffer.
|
||||
#
|
||||
# Requires two instances with their SCL and SDA lines connected together.
|
||||
# Any combination of the below supported boards can be used.
|
||||
#
|
||||
# Notes:
|
||||
# - pull-up resistors may be needed
|
||||
# - alif use 1.8V signalling
|
||||
|
||||
import sys
|
||||
from machine import I2C, I2CTarget
|
||||
|
||||
ADDR = 67
|
||||
|
||||
# Configure pins based on the target.
|
||||
if sys.platform == "alif":
|
||||
i2c_args = (1,) # pins P3_7/P3_6
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "esp32":
|
||||
i2c_args = (1,) # on pins 9/8
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "mimxrt":
|
||||
i2c_args = (0,) # pins 19/18 on Teensy 4.x
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "rp2":
|
||||
i2c_args = (0,)
|
||||
i2c_kwargs = {"scl": 9, "sda": 8}
|
||||
elif sys.platform == "pyboard":
|
||||
i2c_args = ("Y",)
|
||||
i2c_kwargs = {}
|
||||
elif sys.platform == "samd":
|
||||
i2c_args = () # pins SCL/SDA
|
||||
i2c_kwargs = {}
|
||||
elif "zephyr-rpi_pico" in sys.implementation._machine:
|
||||
i2c_args = ("i2c1",) # on gpio7/gpio6
|
||||
i2c_kwargs = {}
|
||||
else:
|
||||
print("Please add support for this test on this platform.")
|
||||
raise SystemExit
|
||||
|
||||
|
||||
def simple_irq(i2c_target):
|
||||
flags = i2c_target.irq().flags()
|
||||
if flags & I2CTarget.IRQ_END_READ:
|
||||
print("IRQ_END_READ", i2c_target.memaddr)
|
||||
if flags & I2CTarget.IRQ_END_WRITE:
|
||||
print("IRQ_END_WRITE", i2c_target.memaddr)
|
||||
|
||||
|
||||
# I2C controller
|
||||
def instance0():
|
||||
i2c = I2C(*i2c_args, **i2c_kwargs)
|
||||
multitest.next()
|
||||
for iteration in range(2):
|
||||
print("controller iteration", iteration)
|
||||
multitest.wait("target stage 1")
|
||||
i2c.writeto_mem(ADDR, 2 + iteration, "0123")
|
||||
multitest.broadcast("controller stage 2")
|
||||
multitest.wait("target stage 3")
|
||||
print(i2c.readfrom_mem(ADDR, 2 + iteration, 4))
|
||||
multitest.broadcast("controller stage 4")
|
||||
print("done")
|
||||
|
||||
|
||||
# I2C target
|
||||
def instance1():
|
||||
buf = bytearray(b"--------")
|
||||
i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR, mem=buf)
|
||||
i2c_target.irq(simple_irq)
|
||||
multitest.next()
|
||||
for iteration in range(2):
|
||||
print("target iteration", iteration)
|
||||
multitest.broadcast("target stage 1")
|
||||
multitest.wait("controller stage 2")
|
||||
print(buf)
|
||||
multitest.broadcast("target stage 3")
|
||||
multitest.wait("controller stage 4")
|
||||
i2c_target.deinit()
|
||||
print("done")
|
||||
16
tests/multi_extmod/machine_i2c_target_memory.py.exp
Normal file
16
tests/multi_extmod/machine_i2c_target_memory.py.exp
Normal file
@@ -0,0 +1,16 @@
|
||||
--- instance0 ---
|
||||
controller iteration 0
|
||||
b'0123'
|
||||
controller iteration 1
|
||||
b'0123'
|
||||
done
|
||||
--- instance1 ---
|
||||
target iteration 0
|
||||
IRQ_END_WRITE 2
|
||||
bytearray(b'--0123--')
|
||||
IRQ_END_READ 2
|
||||
target iteration 1
|
||||
IRQ_END_WRITE 3
|
||||
bytearray(b'--00123-')
|
||||
IRQ_END_READ 3
|
||||
done
|
||||
Reference in New Issue
Block a user