summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/multi_extmod/machine_i2c_target_irq.py137
-rw-r--r--tests/multi_extmod/machine_i2c_target_irq.py.exp15
-rw-r--r--tests/multi_extmod/machine_i2c_target_memory.py79
-rw-r--r--tests/multi_extmod/machine_i2c_target_memory.py.exp16
4 files changed, 247 insertions, 0 deletions
diff --git a/tests/multi_extmod/machine_i2c_target_irq.py b/tests/multi_extmod/machine_i2c_target_irq.py
new file mode 100644
index 000000000..eafd9dfdc
--- /dev/null
+++ b/tests/multi_extmod/machine_i2c_target_irq.py
@@ -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")
diff --git a/tests/multi_extmod/machine_i2c_target_irq.py.exp b/tests/multi_extmod/machine_i2c_target_irq.py.exp
new file mode 100644
index 000000000..a17c8f438
--- /dev/null
+++ b/tests/multi_extmod/machine_i2c_target_irq.py.exp
@@ -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
diff --git a/tests/multi_extmod/machine_i2c_target_memory.py b/tests/multi_extmod/machine_i2c_target_memory.py
new file mode 100644
index 000000000..6b3f0d03e
--- /dev/null
+++ b/tests/multi_extmod/machine_i2c_target_memory.py
@@ -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")
diff --git a/tests/multi_extmod/machine_i2c_target_memory.py.exp b/tests/multi_extmod/machine_i2c_target_memory.py.exp
new file mode 100644
index 000000000..71386cfe7
--- /dev/null
+++ b/tests/multi_extmod/machine_i2c_target_memory.py.exp
@@ -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