Skip to content

Commit 63aacd8

Browse files
nkpro2000srbessman
authored andcommitted
added test for I2CMaster and I2CSlave
1 parent 4615c87 commit 63aacd8

File tree

2 files changed

+279
-5
lines changed

2 files changed

+279
-5
lines changed

PSL/Peripherals.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class I2CMaster():
99
Methods to handle slave independent functionality with the I2C port.
1010
An instance of Labtools.Packet_Handler must be passed to the init function
1111
"""
12+
MAX_BRGVAL = 511
1213

1314
def __init__(self, H):
1415
self.H = H
@@ -60,8 +61,8 @@ def config(self, freq, verbose=True):
6061
self.H.__sendByte__(CP.I2C_CONFIG)
6162
# freq=1/((BRGVAL+1.0)/64e6+1.0/1e7)
6263
BRGVAL = int((1. / freq - 1. / 1e7) * 64e6 - 1)
63-
if BRGVAL > 511:
64-
BRGVAL = 511
64+
if BRGVAL > self.MAX_BRGVAL:
65+
BRGVAL = self.MAX_BRGVAL
6566
if verbose: print('Frequency too low. Setting to :', 1 / ((BRGVAL + 1.0) / 64e6 + 1.0 / 1e7))
6667
self.H.__sendInt__(BRGVAL)
6768
self.H.__get_ack__()
@@ -301,7 +302,7 @@ def readBulk(self, register_address, bytes_to_read):
301302
self.H.__sendByte__(self.address)
302303
self.H.__sendByte__(register_address)
303304
self.H.__sendByte__(bytes_to_read)
304-
data = self.H.fd.read(bytes_to_read)
305+
data = self.H.interface.read(bytes_to_read)
305306
self.H.__get_ack__()
306307
try:
307308
return list(data)
@@ -405,7 +406,7 @@ def __retrievebuffer__(self):
405406
self.H.__sendInt__(i * DATA_SPLITTING)
406407
rem = DATA_SPLITTING * 2 + 1
407408
for _ in range(200):
408-
partial = self.H.fd.read(
409+
partial = self.H.interface.read(
409410
rem) # reading int by int sometimes causes a communication error. this works better.
410411
rem -= len(partial)
411412
data += partial
@@ -423,7 +424,7 @@ def __retrievebuffer__(self):
423424
self.H.__sendInt__(total_int_samples - total_int_samples % DATA_SPLITTING)
424425
rem = 2 * (total_int_samples % DATA_SPLITTING) + 1
425426
for _ in range(20):
426-
partial = self.H.fd.read(
427+
partial = self.H.interface.read(
427428
rem) # reading int by int sometimes causes a communication error. this works better.
428429
rem -= len(partial)
429430
data += partial

tests/test_peripherals_i2c.py

Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
from unittest.mock import Mock, call as H_interface
2+
import pytest
3+
4+
from PSL import commands_proto as CP
5+
from PSL.Peripherals import I2CMaster, I2CSlave, I2C
6+
from PSL.packet_handler import Handler
7+
8+
ADDRESS = 0X52
9+
REGISTER_ADDRESS = 0x06
10+
11+
class MockHandler(Handler):
12+
def connect(self, *args, **kwargs):
13+
pass
14+
15+
@pytest.fixture
16+
def handler():
17+
mock_handler = MockHandler()
18+
mock_handler.interface = Mock()
19+
mock_handler.interface.read.return_value=CP.ACKNOWLEDGE
20+
mock_handler.interface.write.return_value=None
21+
return mock_handler
22+
23+
@pytest.fixture
24+
def master(handler):
25+
return I2CMaster(handler)
26+
27+
@pytest.fixture
28+
def slave(handler):
29+
return I2CSlave(handler, ADDRESS)
30+
31+
class Response:
32+
def __init__(self, interface, responses, default):
33+
self.interface = interface # mocked
34+
self.responses = responses
35+
self.default = default
36+
def __call__(self, request):
37+
if request in self.responses:
38+
self.interface.read.return_value = self.responses[request]
39+
else:
40+
self.interface.read.return_value = self.default
41+
42+
43+
CONFIG = list(map(H_interface.write,[
44+
CP.I2C_HEADER,
45+
CP.I2C_CONFIG,
46+
]))
47+
48+
ACK = [H_interface.read(1)]
49+
50+
def test_config_frequency(master):
51+
MAX_BRGVAL = master.MAX_BRGVAL
52+
53+
# <= MAX_BRGVAL
54+
BRGVAL = MAX_BRGVAL - 1
55+
freq = round(1.0/((BRGVAL+1.0)/64e6+1.0/1e7))
56+
master.config(freq, verbose=True)
57+
calls = CONFIG + [H_interface.write(CP.ShortInt.pack(BRGVAL))] + ACK
58+
assert master.H.interface.method_calls == calls
59+
60+
def test_config_low_frequency(master, capsys):
61+
MAX_BRGVAL = master.MAX_BRGVAL
62+
63+
# > MAX_BRGVAL
64+
BRGVAL = MAX_BRGVAL + 1
65+
freq = round(1.0/((BRGVAL+1.0)/64e6+1.0/1e7))
66+
master.config(freq, verbose=True)
67+
calls = CONFIG + [H_interface.write(CP.ShortInt.pack(MAX_BRGVAL))] + ACK
68+
assert master.H.interface.method_calls == calls
69+
captured = capsys.readouterr()
70+
assert captured.out == f'Frequency too low. Setting to : {1/((MAX_BRGVAL+1.0)/64e6+1.0/1e7)}\n'
71+
72+
def test_scan(master):
73+
address = CP.Byte.pack(((ADDRESS << 1) | 0) & 0xFF)
74+
interface = master.H.interface
75+
success = CP.Byte.pack(1)
76+
responses = {address : success}
77+
78+
interface.write.side_effect = Response(interface, responses, CP.ACKNOWLEDGE)
79+
assert master.scan() == [ADDRESS]
80+
81+
82+
START_READ = list(map(H_interface.write,[
83+
CP.I2C_HEADER,
84+
CP.I2C_START,
85+
CP.Byte.pack(((ADDRESS << 1) | 1) & 0xFF),
86+
]))
87+
88+
START_WRITE = list(map(H_interface.write,[
89+
CP.I2C_HEADER,
90+
CP.I2C_START,
91+
CP.Byte.pack(((ADDRESS << 1) | 0) & 0xFF),
92+
]))
93+
94+
STOP = list(map(H_interface.write,[
95+
CP.I2C_HEADER,
96+
CP.I2C_STOP,
97+
]))
98+
99+
SEND = list(map(H_interface.write,[
100+
CP.I2C_HEADER,
101+
CP.I2C_SEND,
102+
]))
103+
104+
SEND_BURST = list(map(H_interface.write,[
105+
CP.I2C_HEADER,
106+
CP.I2C_SEND_BURST,
107+
]))
108+
109+
RESTART_READ = list(map(H_interface.write,[
110+
CP.I2C_HEADER,
111+
CP.I2C_RESTART,
112+
CP.Byte.pack(((ADDRESS << 1) | 1) & 0xFF),
113+
]))
114+
115+
RESTART_WRITE = list(map(H_interface.write,[
116+
CP.I2C_HEADER,
117+
CP.I2C_RESTART,
118+
CP.Byte.pack(((ADDRESS << 1) | 0) & 0xFF),
119+
]))
120+
121+
READ_MORE = list(map(H_interface.write,[
122+
CP.I2C_HEADER,
123+
CP.I2C_READ_MORE,
124+
]))
125+
126+
READ_END = list(map(H_interface.write,[
127+
CP.I2C_HEADER,
128+
CP.I2C_READ_END,
129+
]))
130+
131+
READ_BULK = list(map(H_interface.write,[
132+
CP.I2C_HEADER,
133+
CP.I2C_READ_BULK,
134+
CP.Byte.pack(ADDRESS),
135+
CP.Byte.pack(REGISTER_ADDRESS),
136+
]))
137+
138+
WRITE_BULK = list(map(H_interface.write,[
139+
CP.I2C_HEADER,
140+
CP.I2C_WRITE_BULK,
141+
CP.Byte.pack(ADDRESS),
142+
]))
143+
144+
CAPTURE_START = list(map(H_interface.write,[
145+
CP.I2C_HEADER,
146+
CP.I2C_START_SCOPE,
147+
CP.Byte.pack(ADDRESS),
148+
CP.Byte.pack(REGISTER_ADDRESS),
149+
]))
150+
151+
def test_send(slave):
152+
slave.start(0)
153+
slave.send(0xFF)
154+
slave.stop()
155+
calls = START_WRITE + ACK
156+
calls += SEND + [H_interface.write(CP.Byte.pack(0xFF))] + ACK
157+
calls += STOP + ACK
158+
assert slave.H.interface.method_calls == calls
159+
160+
def test_send_burst(slave):
161+
slave.start(0)
162+
slave.send_burst(0xFF)
163+
slave.stop()
164+
calls = START_WRITE + ACK
165+
calls += SEND_BURST + [H_interface.write(CP.Byte.pack(0xFF))]
166+
calls += STOP + ACK
167+
assert slave.H.interface.method_calls == calls
168+
169+
def test_restart(slave):
170+
slave.start(1)
171+
slave.restart(0)
172+
slave.stop()
173+
calls = START_READ + ACK
174+
calls += RESTART_WRITE + ACK
175+
calls += STOP + ACK
176+
assert slave.H.interface.method_calls == calls
177+
178+
def test_read(slave):
179+
slave.start(1)
180+
bytes_read = [CP.ACKNOWLEDGE] * 4*2
181+
bytes_read[::2] = [b'd', b'a', b't', b'a']
182+
slave.H.interface.read.side_effect = bytes_read + [CP.ACKNOWLEDGE]
183+
assert slave.read(4) == list(b'data')
184+
slave.stop()
185+
186+
calls = START_READ + ACK
187+
calls += (READ_MORE + [H_interface.read(1)] + ACK)*3
188+
calls += READ_END + [H_interface.read(1)] + ACK
189+
calls += STOP + ACK
190+
assert slave.H.interface.method_calls == calls
191+
192+
def test_simple_read(slave):
193+
bytes_read = [CP.ACKNOWLEDGE] * 4*2
194+
bytes_read[::2] = [b'd', b'a', b't', b'a']
195+
slave.H.interface.read.side_effect = [CP.ACKNOWLEDGE] + bytes_read
196+
assert slave.simpleRead(4) == list(b'data')
197+
198+
calls = START_READ + ACK
199+
calls += (READ_MORE + [H_interface.read(1)] + ACK)*3
200+
calls += READ_END + [H_interface.read(1)] + ACK
201+
assert slave.H.interface.method_calls == calls
202+
203+
def test_simple_read_byte(slave):
204+
bytes_read = [b'\xFF', CP.ACKNOWLEDGE]
205+
slave.H.interface.read.side_effect = [CP.ACKNOWLEDGE] + bytes_read
206+
assert slave.simple_read_byte() == 0xFF
207+
208+
calls = START_READ + ACK
209+
calls += READ_END + [H_interface.read(1)] + ACK
210+
assert slave.H.interface.method_calls == calls
211+
212+
def test_simple_read_int(slave):
213+
bytes_read = [b'\xFF', CP.ACKNOWLEDGE] * 2
214+
slave.H.interface.read.side_effect = [CP.ACKNOWLEDGE] + bytes_read
215+
assert slave.simple_read_int() == 0xFFFF
216+
217+
calls = START_READ + ACK
218+
calls += (READ_MORE + [H_interface.read(1)] + ACK)*1
219+
calls += READ_END + [H_interface.read(1)] + ACK
220+
assert slave.H.interface.method_calls == calls
221+
222+
def test_simple_read_long(slave):
223+
bytes_read = [b'\xFF', CP.ACKNOWLEDGE] * 4
224+
slave.H.interface.read.side_effect = [CP.ACKNOWLEDGE] + bytes_read
225+
assert slave.simple_read_long() == 0xFFFFFFFF
226+
227+
calls = START_READ + ACK
228+
calls += (READ_MORE + [H_interface.read(1)] + ACK)*3
229+
calls += READ_END + [H_interface.read(1)] + ACK
230+
assert slave.H.interface.method_calls == calls
231+
232+
def test_read_bulk(slave):
233+
slave.H.interface.read.side_effect = [b'data', CP.ACKNOWLEDGE]
234+
assert slave.readBulk(REGISTER_ADDRESS, 4) == list(b'data')
235+
236+
calls = READ_BULK + [H_interface.write(CP.Byte.pack(4))]
237+
calls += [H_interface.read(4)] + ACK
238+
assert slave.H.interface.method_calls == calls
239+
240+
def test_read_bulk_byte(slave):
241+
slave.H.interface.read.side_effect = [b'\xFF', CP.ACKNOWLEDGE]
242+
assert slave.read_bulk_byte(REGISTER_ADDRESS) == 0xFF
243+
244+
calls = READ_BULK + [H_interface.write(CP.Byte.pack(1))]
245+
calls += [H_interface.read(1)] + ACK
246+
assert slave.H.interface.method_calls == calls
247+
248+
def test_read_bulk_int(slave):
249+
slave.H.interface.read.side_effect = [b'\xFF'*2, CP.ACKNOWLEDGE]
250+
assert slave.read_bulk_int(REGISTER_ADDRESS) == 0xFFFF
251+
252+
calls = READ_BULK + [H_interface.write(CP.Byte.pack(2))]
253+
calls += [H_interface.read(2)] + ACK
254+
assert slave.H.interface.method_calls == calls
255+
256+
def test_read_bulk_long(slave):
257+
slave.H.interface.read.side_effect = [b'\xFF'*4, CP.ACKNOWLEDGE]
258+
assert slave.read_bulk_long(REGISTER_ADDRESS) == 0xFFFFFFFF
259+
260+
calls = READ_BULK + [H_interface.write(CP.Byte.pack(4))]
261+
calls += [H_interface.read(4)] + ACK
262+
assert slave.H.interface.method_calls == calls
263+
264+
def test_write_bulk(slave):
265+
slave.writeBulk(b'data')
266+
267+
calls = WRITE_BULK + [H_interface.write(CP.Byte.pack(4))]
268+
calls += list(map(H_interface.write, [b'd',b'a',b't',b'a']))
269+
calls += ACK
270+
assert slave.H.interface.method_calls == calls
271+
272+
def test_capture(slave):
273+
pass #TODO

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy