Skip to content

Commit 6afd1f7

Browse files
committed
Address review feedback.
1 parent 88250ce commit 6afd1f7

File tree

1 file changed

+82
-37
lines changed

1 file changed

+82
-37
lines changed

notecard/notecard.py

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ class SerialLockTimeout(Exception):
5454

5555
pass
5656

57-
use_i2c_lock = not use_periphery and sys.implementation.name != 'micropython'
58-
5957
NOTECARD_I2C_ADDRESS = 0x17
6058

6159
# The notecard is a real-time device that has a fixed size interrupt buffer.
@@ -109,8 +107,8 @@ def i2c_lock(fn):
109107

110108
def decorator(self, *args, **kwargs):
111109
retries = 5
112-
while use_i2c_lock and retries != 0:
113-
if self.i2c.try_lock():
110+
while retries != 0:
111+
if self.lock():
114112
break
115113

116114
retries -= 1
@@ -123,8 +121,7 @@ def decorator(self, *args, **kwargs):
123121
try:
124122
ret = fn(self, *args, **kwargs)
125123
finally:
126-
if use_i2c_lock:
127-
self.i2c.unlock()
124+
self.unlock()
128125

129126
return ret
130127

@@ -306,24 +303,24 @@ def __init__(self, uart_id, debug=False):
306303
class OpenI2C(Notecard):
307304
"""Notecard class for I2C communication."""
308305

306+
def _write(self, data):
307+
write_length = bytearray(1)
308+
write_length[0] = len(data)
309+
310+
# Send a message with the length of the incoming bytes followed
311+
# by the bytes themselves.
312+
self._platform_write(write_length, data)
313+
309314
def _transmit(self, data):
310315
chunk_offset = 0
311316
data_left = len(data)
312317
sent_in_seg = 0
313-
write_length = bytearray(1)
314318

315319
while data_left > 0:
316320
chunk_len = min(data_left, self.max)
317-
write_length[0] = chunk_len
318321
write_data = data[chunk_offset:chunk_offset + chunk_len]
319322

320-
# Send a message with the length of the incoming bytes followed
321-
# by the bytes themselves.
322-
if use_periphery:
323-
msgs = [I2C.Message(write_length + write_data)]
324-
self.i2c.transfer(self.addr, msgs)
325-
else:
326-
self.i2c.writeto(self.addr, write_length + write_data)
323+
self._write(write_data)
327324

328325
chunk_offset += chunk_len
329326
data_left -= chunk_len
@@ -335,35 +332,29 @@ def _transmit(self, data):
335332

336333
time.sleep(I2C_CHUNK_DELAY_MS / 1000)
337334

335+
def _read(self, length):
336+
initiate_read = bytearray(2)
337+
# 0 indicates we are reading from the Notecard.
338+
initiate_read[0] = 0
339+
# This indicates how many bytes we are prepared to read.
340+
initiate_read[1] = length
341+
# read_buf is a buffer to store the data we're reading.
342+
# length accounts for the payload and the +2 is for the header. The
343+
# header sent by the Notecard has one byte to indicate the number of
344+
# bytes still available to read and a second byte to indicate the number
345+
# of bytes coming in the current chunk.
346+
read_buf = bytearray(length + 2)
347+
348+
return self._platform_read(initiate_read, read_buf)
349+
338350
def _receive(self, timeout_secs, chunk_delay_secs, wait_for_newline):
339351
chunk_len = 0
340352
received_newline = False
341353
start = start_timeout()
342354
read_data = bytearray()
343355

344356
while True:
345-
initiate_read = bytearray(2)
346-
# 0 indicates we are reading from the Notecard.
347-
initiate_read[0] = 0
348-
# This indicates how many bytes we are prepared to read.
349-
initiate_read[1] = chunk_len
350-
# read_buf is a buffer to store the data we're reading.
351-
# chunk_len accounts for the payload and the +2 is for the
352-
# header. The header sent by the Notecard has one byte to
353-
# indicate the number of bytes still available to read and a
354-
# second byte to indicate the number of bytes coming in the
355-
# current chunk.
356-
read_buf = bytearray(chunk_len + 2)
357-
358-
if use_periphery:
359-
msgs = [I2C.Message(initiate_read), I2C.Message(read_buf, read=True)]
360-
self.i2c.transfer(self.addr, msgs)
361-
read_buf = msgs[1].data
362-
elif sys.implementation.name == 'micropython':
363-
self.i2c.writeto(self.addr, initiate_read, False)
364-
self.i2c.readfrom_into(self.addr, read_buf)
365-
else:
366-
self.i2c.writeto_then_readfrom(self.addr, initiate_read, read_buf)
357+
read_buf = self._read(chunk_len)
367358

368359
# The number of bytes still available to read.
369360
num_bytes_available = read_buf[0]
@@ -420,13 +411,55 @@ def Reset(self):
420411
# Read from the Notecard until there's nothing left to read.
421412
self._receive(0, .001, False)
422413

414+
def _linux_write(self, length, data):
415+
msgs = [I2C.Message(length + data)]
416+
self.i2c.transfer(self.addr, msgs)
417+
418+
def _non_linux_write(self, length, data):
419+
self.i2c.writeto(self.addr, length + data)
420+
421+
def _linux_read(self, initiate_read_msg, read_buf):
422+
msgs = [I2C.Message(initiate_read_msg), I2C.Message(read_buf, read=True)]
423+
self.i2c.transfer(self.addr, msgs)
424+
read_buf = msgs[1].data
425+
426+
return read_buf
427+
428+
def _micropython_read(self, initiate_read_msg, read_buf):
429+
self.i2c.writeto(self.addr, initiate_read_msg, False)
430+
self.i2c.readfrom_into(self.addr, read_buf)
431+
432+
return read_buf
433+
434+
def _circuitpython_read(self, initiate_read_msg, read_buf):
435+
self.i2c.writeto_then_readfrom(self.addr, initiate_read_msg, read_buf)
436+
437+
return read_buf
438+
423439
def __init__(self, i2c, address, max_transfer, debug=False):
424440
"""Initialize the Notecard before a reset."""
425441
super().__init__(debug)
426442
self._user_agent['req_interface'] = 'i2c'
427443
self._user_agent['req_port'] = address
428444

429445
self.i2c = i2c
446+
447+
def i2c_no_op_try_lock(*args, **kwargs):
448+
"""No-op lock function."""
449+
return True
450+
451+
def i2c_no_op_unlock(*args, **kwargs):
452+
"""No-op unlock function."""
453+
pass
454+
455+
use_i2c_lock = not use_periphery and sys.implementation.name != 'micropython'
456+
if use_i2c_lock:
457+
self.lock = self.i2c.try_lock
458+
self.unlock = self.i2c.unlock
459+
else:
460+
self.lock = i2c_no_op_try_lock
461+
self.unlock = i2c_no_op_unlock
462+
430463
if address == 0:
431464
self.addr = NOTECARD_I2C_ADDRESS
432465
else:
@@ -436,4 +469,16 @@ def __init__(self, i2c, address, max_transfer, debug=False):
436469
else:
437470
self.max = max_transfer
438471

472+
if use_periphery:
473+
self._platform_write = self._linux_write
474+
self._platform_read = self._linux_read
475+
elif sys.implementation.name == 'micropython':
476+
self._platform_write = self._non_linux_write
477+
self._platform_read = self._micropython_read
478+
elif sys.implementation.name == 'circuitpython':
479+
self._platform_write = self._non_linux_write
480+
self._platform_read = self._circuitpython_read
481+
else:
482+
raise NotImplementedError(f'Unsupported platform: {sys.implementation.name}')
483+
439484
self.Reset()

0 commit comments

Comments
 (0)