Skip to content

Commit

Permalink
Make changes to support binary transfers.
Browse files Browse the repository at this point in the history
- 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).
  • Loading branch information
haydenroche5 committed Sep 30, 2023
1 parent 1ede5d6 commit a656fb2
Show file tree
Hide file tree
Showing 7 changed files with 1,875 additions and 437 deletions.
33 changes: 33 additions & 0 deletions notecard/crc32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Module for computing the CRC32 of arbitrary data."""

crc32_lookup_table = [
0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC, 0x76DC4190, 0x6B6B51F4,
0x4DB26158, 0x5005713C, 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
]


def _logical_rshift(val, shift_amount, num_bits=32):
"""Logcally right shift `val` by `shift_amount` bits.
Logical right shift (i.e. right shift that fills with 0s instead of the
sign bit) isn't supported natively in Python. This is a simple
implementation. See:
https://realpython.com/python-bitwise-operators/#arithmetic-vs-logical-shift
"""
unsigned_val = val % (1 << num_bits)
return unsigned_val >> shift_amount


def crc32(data):
"""Compute CRC32 of the given data.
Small lookup-table half-byte CRC32 algorithm based on:
https://create.stephan-brumme.com/crc32/#half-byte
"""
crc = ~0
for idx in range(len(data)):
crc = crc32_lookup_table[(crc ^ data[idx]) & 0x0F] ^ _logical_rshift(crc, 4)
crc = crc32_lookup_table[(crc ^ _logical_rshift(data[idx], 4)) & 0x0F] ^ _logical_rshift(crc, 4)

return ~crc & 0xffffffff
Loading

0 comments on commit a656fb2

Please sign in to comment.