Skip to content

Commit 8b6c35a

Browse files
Merge pull request #157 from christiansandberg/custom-crc-algo
Allow to override CRC algorithm for block transfer
2 parents 9cbc92c + a9f8deb commit 8b6c35a

2 files changed

Lines changed: 23 additions & 7 deletions

File tree

canopen/sdo/base.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import binascii
12
try:
23
from collections.abc import Mapping
34
except ImportError:
@@ -7,8 +8,24 @@
78
from .. import variable
89

910

11+
class CrcXmodem(object):
12+
"""Mimics CrcXmodem from crccheck."""
13+
14+
def __init__(self):
15+
self._value = 0
16+
17+
def process(self, data):
18+
self._value = binascii.crc_hqx(data, self._value)
19+
20+
def final(self):
21+
return self._value
22+
23+
1024
class SdoBase(Mapping):
1125

26+
#: The CRC algorithm used for block transfers
27+
crc_cls = CrcXmodem
28+
1229
def __init__(self, rx_cobid, tx_cobid, od):
1330
"""
1431
:param int rx_cobid:

canopen/sdo/client.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import struct
22
import logging
33
import io
4-
import binascii
54
import time
65
try:
76
import queue
@@ -458,7 +457,7 @@ def __init__(self, sdo_client, index, subindex=0):
458457
self._done = False
459458
self.sdo_client = sdo_client
460459
self.pos = 0
461-
self._crc = 0
460+
self._crc = sdo_client.crc_cls()
462461
self._server_crc = None
463462
self._ackseq = 0
464463

@@ -523,9 +522,9 @@ def read(self, size=-1):
523522
else:
524523
data = response[1:8]
525524
if self.crc_supported:
526-
self._crc = binascii.crc_hqx(data, self._crc)
525+
self._crc.process(data)
527526
if self._done:
528-
if self._server_crc != self._crc:
527+
if self._server_crc != self._crc.final():
529528
self.sdo_client.abort(0x05040004)
530529
raise SdoCommunicationError("CRC is not OK")
531530
logger.info("CRC is OK")
@@ -612,7 +611,7 @@ def __init__(self, sdo_client, index, subindex=0, size=None):
612611
self.pos = 0
613612
self._done = False
614613
self._seqno = 0
615-
self._crc = 0
614+
self._crc = sdo_client.crc_cls()
616615
self._last_bytes_sent = 0
617616
command = REQUEST_BLOCK_DOWNLOAD | INITIATE_BLOCK_TRANSFER | CRC_SUPPORTED
618617
request = bytearray(8)
@@ -694,7 +693,7 @@ def send(self, b, end=False):
694693
self.pos += len(b)
695694
if self.crc_supported:
696695
# Calculate CRC
697-
self._crc = binascii.crc_hqx(b, self._crc)
696+
self._crc.process(b)
698697
if self._seqno >= self._blksize:
699698
# End of this block, wait for ACK
700699
self._block_ack()
@@ -738,7 +737,7 @@ def close(self):
738737
request[0] = command
739738
if self.crc_supported:
740739
# Add CRC
741-
struct.pack_into("<H", request, 1, self._crc)
740+
struct.pack_into("<H", request, 1, self._crc.final())
742741
logger.debug("Ending block transfer...")
743742
response = self.sdo_client.request_response(request)
744743
res_command, = struct.unpack_from("B", response)

0 commit comments

Comments
 (0)