Skip to content

Commit ba7449b

Browse files
committed
tests/extmod_hardware: Add test for I2CTarget.
Signed-off-by: Damien George <[email protected]>
1 parent 6fda662 commit ba7449b

File tree

1 file changed

+189
-0
lines changed

1 file changed

+189
-0
lines changed
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# Test machine.I2CTarget.
2+
#
3+
# IMPORTANT: This test requires hardware connections: a SoftI2C instance must be
4+
# wired to a hardware I2C target.
5+
6+
import sys
7+
8+
try:
9+
from machine import Pin, SoftI2C, I2CTarget
10+
except ImportError:
11+
print("SKIP")
12+
raise SystemExit
13+
14+
import unittest
15+
16+
ADDR = 67
17+
18+
# Configure pins based on the target.
19+
if sys.platform == "alif" and sys.implementation._build == "ALIF_ENSEMBLE":
20+
args_controller = {"scl": "P1_1", "sda": "P1_0"}
21+
args_target = (0,)
22+
elif sys.platform == "rp2":
23+
args_controller = {"scl": 5, "sda": 4}
24+
args_target = (1,)
25+
elif sys.platform == "pyboard":
26+
if sys.implementation._build == "NUCLEO_WB55":
27+
args_controller = {"scl": "B8", "sda": "B9"}
28+
args_target = (3,)
29+
else:
30+
args_controller = {"scl": "X1", "sda": "X2"}
31+
args_target = ("X",)
32+
elif sys.platform == "zephyr":
33+
if "zephyr-nucleo_wb55rg" in sys.implementation._machine:
34+
# PB8=I2C1_SCL, PB9=I2C1_SDA (on Arduino header D15/D14)
35+
# PC0=I2C3_SCL, PC1=I2C3_SDA (on Arduino header A0/A1)
36+
args_controller = {"scl": Pin(("gpiob", 8)), "sda": Pin(("gpiob", 9))}
37+
args_target = ("i2c3",)
38+
elif "zephyr-rpi_pico" in sys.implementation._machine:
39+
args_controller = {"scl": Pin(("gpio0", 5)), "sda": Pin(("gpio0", 4))}
40+
args_target = ("i2c1",)
41+
else:
42+
print("Please add support for this test on this zephyr platform.")
43+
raise SystemExit
44+
else:
45+
print("Please add support for this test on this platform.")
46+
raise SystemExit
47+
48+
49+
def config_pull_up():
50+
Pin(args_controller["scl"], Pin.OPEN_DRAIN, Pin.PULL_UP)
51+
Pin(args_controller["sda"], Pin.OPEN_DRAIN, Pin.PULL_UP)
52+
53+
54+
class TestMemory(unittest.TestCase):
55+
@classmethod
56+
def setUpClass(cls):
57+
cls.mem = bytearray(8)
58+
cls.i2c = SoftI2C(**args_controller)
59+
cls.i2c_target = I2CTarget(*args_target, addr=ADDR, mem=cls.mem)
60+
config_pull_up()
61+
62+
@classmethod
63+
def tearDownClass(cls):
64+
cls.i2c_target.deinit()
65+
66+
def test_scan(self):
67+
self.assertEqual(self.i2c.scan(), [ADDR])
68+
69+
def test_write(self):
70+
self.mem[:] = b"01234567"
71+
self.i2c.writeto_mem(ADDR, 0, b"test")
72+
self.assertEqual(self.mem, bytearray(b"test4567"))
73+
self.i2c.writeto_mem(ADDR, 4, b"TEST")
74+
self.assertEqual(self.mem, bytearray(b"testTEST"))
75+
76+
def test_write_wrap(self):
77+
self.mem[:] = b"01234567"
78+
self.i2c.writeto_mem(ADDR, 6, b"test")
79+
self.assertEqual(self.mem, bytearray(b"st2345te"))
80+
self.i2c.writeto_mem(ADDR, 0, b"testTESTmore")
81+
self.assertEqual(self.mem, bytearray(b"moreTEST"))
82+
83+
def test_read(self):
84+
self.mem[:] = b"01234567"
85+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 4), b"0123")
86+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 4, 4), b"4567")
87+
88+
def test_read_wrap(self):
89+
self.mem[:] = b"01234567"
90+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 4), b"0123")
91+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 2, 4), b"2345")
92+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 6, 4), b"6701")
93+
self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 12), b"012345670123")
94+
95+
96+
class TestIRQ(unittest.TestCase):
97+
@staticmethod
98+
def irq_handler(i2c_target, buf=bytearray(1)):
99+
flags = i2c_target.irq().flags()
100+
TestIRQ.events[TestIRQ.num_events] = flags
101+
TestIRQ.num_events += 1
102+
if flags & I2CTarget.IRQ_READ_REQ:
103+
i2c_target.write(b"Y")
104+
if flags & I2CTarget.IRQ_WRITE_REQ:
105+
i2c_target.readinto(buf)
106+
TestIRQ.events[TestIRQ.num_events] = buf[0]
107+
TestIRQ.num_events += 1
108+
109+
@classmethod
110+
def setUpClass(cls):
111+
cls.events = [0] * 8
112+
cls.num_events = 0
113+
cls.i2c = SoftI2C(**args_controller)
114+
cls.i2c_target = I2CTarget(*args_target, addr=ADDR)
115+
cls.i2c_target.irq(
116+
TestIRQ.irq_handler,
117+
I2CTarget.IRQ_ADDR_MATCH
118+
| I2CTarget.IRQ_WRITE_REQ
119+
| I2CTarget.IRQ_READ_REQ
120+
| I2CTarget.IRQ_END,
121+
hard=True,
122+
)
123+
config_pull_up()
124+
125+
@classmethod
126+
def tearDownClass(cls):
127+
cls.i2c_target.deinit()
128+
129+
def test_scan(self):
130+
TestIRQ.num_events = 0
131+
self.i2c.scan()
132+
self.assertEqual(
133+
self.events[: self.num_events],
134+
[
135+
I2CTarget.IRQ_ADDR_MATCH,
136+
I2CTarget.IRQ_END,
137+
],
138+
)
139+
140+
def test_write(self):
141+
TestIRQ.num_events = 0
142+
self.i2c.writeto(ADDR, b"XYZ")
143+
self.assertEqual(
144+
self.events[: self.num_events],
145+
[
146+
I2CTarget.IRQ_ADDR_MATCH,
147+
I2CTarget.IRQ_WRITE_REQ,
148+
ord(b"X"),
149+
I2CTarget.IRQ_WRITE_REQ,
150+
ord(b"Y"),
151+
I2CTarget.IRQ_WRITE_REQ,
152+
ord(b"Z"),
153+
I2CTarget.IRQ_END,
154+
],
155+
)
156+
157+
def test_read(self):
158+
TestIRQ.num_events = 0
159+
self.assertEqual(self.i2c.readfrom(ADDR, 1), b"Y")
160+
self.assertEqual(
161+
self.events[: self.num_events],
162+
[
163+
I2CTarget.IRQ_ADDR_MATCH,
164+
I2CTarget.IRQ_READ_REQ,
165+
I2CTarget.IRQ_READ_REQ,
166+
I2CTarget.IRQ_END,
167+
],
168+
)
169+
170+
def test_write_read(self):
171+
TestIRQ.num_events = 0
172+
self.i2c.writeto(ADDR, b"X", False)
173+
self.assertEqual(self.i2c.readfrom(ADDR, 1), b"Y")
174+
self.assertEqual(
175+
self.events[: self.num_events],
176+
[
177+
I2CTarget.IRQ_ADDR_MATCH,
178+
I2CTarget.IRQ_WRITE_REQ,
179+
ord(b"X"),
180+
I2CTarget.IRQ_ADDR_MATCH,
181+
I2CTarget.IRQ_READ_REQ,
182+
I2CTarget.IRQ_READ_REQ,
183+
I2CTarget.IRQ_END,
184+
],
185+
)
186+
187+
188+
if __name__ == "__main__":
189+
unittest.main()

0 commit comments

Comments
 (0)