Skip to content

Commit a656fb2

Browse files
committed
Make changes to support binary transfers.
- Add CRC support. - Align serial and I2C code with note-c. This encompasses mimicking the algorithms used in note-c and also things like delay lengths, number of retries, transaction timeout lengths, etc. - Align transaction logic with note-c. The majority of this work is in the reworked `Transaction` function, which is analogous to `noteTransactionShouldLock` in note-c. - Rework serial/I2C locking so that the lock can be held for the entirety of a binary transfer. For example, for a binary receive operation, the host needs to send a `card.binary.get` and then immediately receive the binary data from the Notecard. The serial/I2C lock should be held for the entirety of this operation, rather than be released after the `card.binary.get` and reacquired for the receipt of the binary data. - Add two methods for both serial and I2C: `transmit` and `receive`. `transmit` is used to transmit arbitrary bytes to the Notecard (e.g. after `card.binary.put`). `read_until_newline` is used to read a stream of bytes from the Notecard, stopping after reading a newline (e.g. after a `card.binary.get`). These are analogous to the `chunked(Receive|Transmit)` functions in note-c. - Overhaul unit testing. This commit adds many new unit tests, in addition to reorganizing things. Tests for the `Notecard` base class are in test_notecard.py. `OpenSerial` tests are in test_serial.py, and `OpenI2C` tests are in test_i2c.py. There is a some code repetition here, especially between the `_transact` and `Reset` methods of `OpenSerial` and `OpenI2C`. Again, this follows the pattern in note-c and was done consciously. We may want to factor out that repetition in the future, but for now, I'm prioritizing parity with the "source of truth" (note-c).
1 parent 1ede5d6 commit a656fb2

File tree

7 files changed

+1875
-437
lines changed

7 files changed

+1875
-437
lines changed

notecard/crc32.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Module for computing the CRC32 of arbitrary data."""
2+
3+
crc32_lookup_table = [
4+
0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
5+
0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
6+
0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
7+
]
8+
9+
10+
def _logical_rshift(val, shift_amount, num_bits=32):
11+
"""Logcally right shift `val` by `shift_amount` bits.
12+
13+
Logical right shift (i.e. right shift that fills with 0s instead of the
14+
sign bit) isn't supported natively in Python. This is a simple
15+
implementation. See:
16+
https://realpython.com/python-bitwise-operators/#arithmetic-vs-logical-shift
17+
"""
18+
unsigned_val = val % (1 << num_bits)
19+
return unsigned_val >> shift_amount
20+
21+
22+
def crc32(data):
23+
"""Compute CRC32 of the given data.
24+
25+
Small lookup-table half-byte CRC32 algorithm based on:
26+
https://create.stephan-brumme.com/crc32/#half-byte
27+
"""
28+
crc = ~0
29+
for idx in range(len(data)):
30+
crc = crc32_lookup_table[(crc ^ data[idx]) & 0x0F] ^ _logical_rshift(crc, 4)
31+
crc = crc32_lookup_table[(crc ^ _logical_rshift(data[idx], 4)) & 0x0F] ^ _logical_rshift(crc, 4)
32+
33+
return ~crc & 0xffffffff

0 commit comments

Comments
 (0)