diff --git a/pySerialTransfer/CRC.py b/pySerialTransfer/CRC.py new file mode 100644 index 0000000..1cfba69 --- /dev/null +++ b/pySerialTransfer/CRC.py @@ -0,0 +1,56 @@ +import sys + + +class CRC(object): + def __init__(self, polynomial=0x9B, crc_len=8): + self.poly = polynomial & 0xFF + self.crc_len = crc_len + self.table_len = pow(2, crc_len) + self.cs_table = [' ' for x in range(self.table_len)] + + self.generate_table() + + def generate_table(self): + for i in range(len(self.cs_table)): + curr = i + + for j in range(8): + if (curr & 0x80) != 0: + curr = ((curr << 1) & 0xFF) ^ self.poly + else: + curr <<= 1 + + self.cs_table[i] = curr + + def print_table(self): + for i in range(len(self.cs_table)): + sys.stdout.write(hex(self.cs_table[i]).upper().replace('X', 'x')) + + if (i + 1) % 16: + sys.stdout.write(' ') + else: + sys.stdout.write('\n') + + def calculate(self, arr, dist=None): + crc = 0 + + try: + if dist: + indicies = dist + else: + indicies = len(arr) + + for i in range(indicies): + crc = self.cs_table[crc ^ arr[i]] + + except TypeError: + crc = self.cs_table[arr] + + return crc + + +if __name__ == '__main__': + crc = CRC() + print(crc.print_table()) + print(' ') + print(hex(crc.calculate(0x31)).upper().replace('X', 'x')) \ No newline at end of file diff --git a/pySerialTransfer/__init__.py b/pySerialTransfer/__init__.py index b6e690f..1e136c6 100644 --- a/pySerialTransfer/__init__.py +++ b/pySerialTransfer/__init__.py @@ -1 +1 @@ -from . import * +from . import * diff --git a/pySerialTransfer/pySerialTransfer.py b/pySerialTransfer/pySerialTransfer.py index 3d3d95a..852d6cc 100644 --- a/pySerialTransfer/pySerialTransfer.py +++ b/pySerialTransfer/pySerialTransfer.py @@ -1,11 +1,12 @@ import serial from platform import system +from CRC import CRC CONTINUE = 2 NEW_DATA = 1 NO_DATA = 0 -CHECKSUM_ERROR = -1 +CRC_ERROR = -1 PAYLOAD_ERROR = -2 STOP_BYTE_ERROR = -3 @@ -18,7 +19,7 @@ find_overhead_byte = 1 find_payload_len = 2 find_payload = 3 -find_checksum = 4 +find_crc = 4 find_end_byte = 5 @@ -43,8 +44,8 @@ def __init__(self, port_num, baud=115200): :return: void ''' - self.txBuff = (', ' * (MAX_PACKET_SIZE - 1)).split(',') - self.rxBuff = (', ' * (MAX_PACKET_SIZE - 1)).split(',') + self.txBuff = [' ' for i in (MAX_PACKET_SIZE - 1)] + self.rxBuff = [' ' for i in (MAX_PACKET_SIZE - 1)] self.bytesRead = 0 self.status = 0 @@ -57,6 +58,7 @@ def __init__(self, port_num, baud=115200): else: port_name = '/dev/ttyUSB{}'.format(port_num) + self.crc = CRC() self.connection = serial.Serial() self.connection.port = port_name self.connection.baudrate = baud @@ -150,32 +152,6 @@ def stuff_packet(self, pay_len): if self.txBuff[i] == START_BYTE: self.txBuff[i] = refByte - i refByte = i - - def checksum(self, arr, pay_len): - ''' - Description: - ------------ - Determine the 8-bit checksum of a given number of elements of - a given array - - :param arr: list - list to calculate the checksum over - :param pay_len: int - number of bytes in the payload - - :return checksum: int - resulting checksum - ''' - - checksum = 0 - - for i in range(pay_len): - if type(arr[i]) == str: - checksum += ord(arr[i]) - else: - checksum += int(arr[i]) - - checksum = ~checksum - checksum = checksum & 0xFF - - return checksum def send(self, message_len): ''' @@ -195,7 +171,7 @@ def send(self, message_len): try: self.calc_overhead(message_len) self.stuff_packet(message_len) - found_checksum = self.checksum(self.txBuff, message_len) + found_checksum = self.crc.calculate(self.txBuff, message_len) stack.append(START_BYTE) stack.append(self.overheadByte) @@ -293,17 +269,17 @@ def available(self): self.payIndex += 1 if self.payIndex == self.bytesToRec: - self.state = find_checksum + self.state = find_crc - elif self.state == find_checksum:############################## - found_checksum = self.checksum(self.rxBuff, self.bytesToRec) + elif self.state == find_crc:################################### + found_checksum = self.crc.calculate(self.rxBuff, self.bytesToRec) if found_checksum == recChar: self.state = find_end_byte else: self.bytesRead = 0 self.state = find_start_byte - self.status = CHECKSUM_ERROR + self.status = CRC_ERROR return self.bytesRead elif self.state == find_end_byte:##############################