Removed function for calculation CRC

This commit is contained in:
Christian Sueltrop 2013-11-20 11:28:18 +01:00
parent 358a871493
commit c2bd9b792f

View file

@ -1,181 +1,181 @@
# -*- coding: UTF-8 -*-
'''
Created on 06.07.2012
@author: Christian Sültrop
'''
import array
import sys
from pycrc import Crc
class CanMessage(object):
'''
A CAN message.
A CAN message is represented by an ID, a Length in bytes, a CycleTime in ms, an array of Signals, and Data.
When calling the composeData() method, the data from all Signals is copied into the Data array of the message,
with respect to the signal begin and length definitions from the CanSignal objects in Signals.
'''
def __init__(self, MessageId, MessageLength, MessageCycleTime, Label):
'''
Create a new CanMessage object.
@param MessageId: The CAN ID. Valid range 0x00 to 0x7ff.
@param MessageLength: The message length in bytes.
@param messageCycleTime: Cycle time in ms.
'''
# Instance variables
self.Signals = {}
self.Data = array.array('B')
# check message length for validity
if MessageLength > 8:
sys.exit('Invalid message MessageLength')
# check message ID for validity
if (MessageId < 0x000) or (MessageId > 0x7ff):
sys.exit('Invalid MessageId')
# assign the parameters
self.Length = MessageLength
self.Id = MessageId
self.CycleTime = MessageCycleTime
self.Label = Label
# create an initial array of message data
for i in range(0, self.Length):
self.Data.append(0x00)
def addSignal(self, CanSignal):
'''
Add a Signal of type CanSignal to the list of signals.
@param CanSignal: The signal to add to the list of signals.
'''
self.Signals.update({CanSignal.Label: CanSignal})
def removeSignal(self, CanSignalLabel):
try:
self.Signals.pop(CanSignalLabel)
except:
pass
def clearSignals(self):
self.Signals = {}
def composeData(self):
'''
Takes the CanSignals from the list in self.Signals and copies
the data that is stored in their Data fields into the Data field
of the CanMessage object. The position where to copy the data
is defined in the Begin and Length fields of the CanSignal objects.
'''
for sigKey in self.Signals:
sig = self.Signals[sigKey]
srcBegin = 0 # reading the source data (from the Signal definition) always starts at the first bit
tgtBegin = sig.Begin # where the source data goes is defined in the Begin field of the CanSignal object
srcByteNo = (srcBegin/8) # will be 0 if srcBegin == 0
srcBitNo = (srcBegin%8) # will be 0 if srcBegin == 0
tgtByteNo = (tgtBegin/8) # get the byte and bit numbers
tgtBitNo = (tgtBegin%8) # for the target (the CanMessage object) array
for i in range(0, sig.Length):
# copy the source data bits to the target
# OR # get srcBitNo from srcByteNo and shift it to tgtBitNo
if tgtByteNo >= self.Length:
sys.exit('Signal does not fit into message!')
tmp = sig.Data[srcByteNo]
tmp = tmp >> srcBitNo
tmp = tmp & 0x01
if tmp == 1: # the bit shall be set
self.Data[tgtByteNo] |= (1 << tgtBitNo)
else: # the bit shall be cleared
self.Data[tgtByteNo] &= ~(1 << tgtBitNo)
# increment the counters
srcBitNo += 1
if srcBitNo >= 8: # on bit counter overflow, increment the byte counter and reset the bit counter
srcBitNo = 0
srcByteNo += 1
tgtBitNo += 1
if tgtBitNo >= 8:
tgtBitNo = 0
tgtByteNo += 1
'''
Takes the CAN message data and decomposes it into its signals.
This method is basically the reversion of the method composeData.
'''
def decomposeData(self):
for sigKey in self.Signals:
sig = self.Signals[sigKey]
tgtBegin = 0 # writing the target data (to the signal) always starts at the first byte
srcBegin = sig.Begin # where the target data is in the message is defined in the Begin field of the CanSignal object. Unit: bits
tgtByteNo = tgtBegin/8 # will be 0 if tgtBegin == 0
tgtBitNo = tgtBegin%8 # will be 0 if tgtBegin == 0
srcByteNo = srcBegin/8 # get the byte and bit numbers
srcBitNo = srcBegin%8 # for the source (the CanMessage object) array
for i in range(0, sig.Length):
# copy the source data bits into the target
if srcByteNo >= self.Length:
sys.exit('Signal data not in message (message too short)')
tmp = (self.Data[srcByteNo] & (1<<srcBitNo))
if tmp > 0: # the bit shall be set
sig.Data[tgtByteNo] |= (1<<tgtBitNo)
else: # the bit shall be cleared
sig.Data[tgtByteNo] &= ~(1<<tgtBitNo)
# increment the counters
srcBitNo += 1
if srcBitNo >= 8: # on bit counter overflow, increment the byte counter and reset the bit counter
srcBitNo = 0
srcByteNo += 1
tgtBitNo += 1
if tgtBitNo >= 8:
tgtBitNo = 0
tgtByteNo += 1
self.Signals[sigKey] = sig
'''
Calculate the CRC checksum over the whole message.
The VW implementation is a very simple implementation that cannot really be called a CRC: They simply do a bitwise
XOR on the message data.
If this is true for all checksums is not certain! Has been tested for mMotor_5 and mMotor_6 only!
'''
def calculateCRC(self):
#crc = Crc(width=8, poly=0x01, reflect_in = False, reflect_out = False, xor_in = 0xff, xor_out = 0xff) # configure the crc calculator according to the VW parameters
#self.composeData()
#data = self.Data.tostring()
#my_crc = crc.bit_by_bit_fast(data)
#return my_crc
my_crc = 0;
for i in range(len(self.Data)):
my_crc ^= self.Data[i]
return my_crc
# -*- coding: UTF-8 -*-
'''
Created on 06.07.2012
@author: Christian Sültrop
'''
import array
import sys
#from pycrc import Crc
class CanMessage(object):
'''
A CAN message.
A CAN message is represented by an ID, a Length in bytes, a CycleTime in ms, an array of Signals, and Data.
When calling the composeData() method, the data from all Signals is copied into the Data array of the message,
with respect to the signal begin and length definitions from the CanSignal objects in Signals.
'''
def __init__(self, MessageId, MessageLength, MessageCycleTime, Label):
'''
Create a new CanMessage object.
@param MessageId: The CAN ID. Valid range 0x00 to 0x7ff.
@param MessageLength: The message length in bytes.
@param messageCycleTime: Cycle time in ms.
'''
# Instance variables
self.Signals = {}
self.Data = array.array('B')
# check message length for validity
if MessageLength > 8:
sys.exit('Invalid message MessageLength')
# check message ID for validity
if (MessageId < 0x000) or (MessageId > 0x7ff):
sys.exit('Invalid MessageId')
# assign the parameters
self.Length = MessageLength
self.Id = MessageId
self.CycleTime = MessageCycleTime
self.Label = Label
# create an initial array of message data
for i in range(0, self.Length):
self.Data.append(0x00)
def addSignal(self, CanSignal):
'''
Add a Signal of type CanSignal to the list of signals.
@param CanSignal: The signal to add to the list of signals.
'''
self.Signals.update({CanSignal.Label: CanSignal})
def removeSignal(self, CanSignalLabel):
try:
self.Signals.pop(CanSignalLabel)
except:
pass
def clearSignals(self):
self.Signals = {}
def composeData(self):
'''
Takes the CanSignals from the list in self.Signals and copies
the data that is stored in their Data fields into the Data field
of the CanMessage object. The position where to copy the data
is defined in the Begin and Length fields of the CanSignal objects.
'''
for sigKey in self.Signals:
sig = self.Signals[sigKey]
srcBegin = 0 # reading the source data (from the Signal definition) always starts at the first bit
tgtBegin = sig.Begin # where the source data goes is defined in the Begin field of the CanSignal object
srcByteNo = (srcBegin/8) # will be 0 if srcBegin == 0
srcBitNo = (srcBegin%8) # will be 0 if srcBegin == 0
tgtByteNo = (tgtBegin/8) # get the byte and bit numbers
tgtBitNo = (tgtBegin%8) # for the target (the CanMessage object) array
for i in range(0, sig.Length):
# copy the source data bits to the target
# OR # get srcBitNo from srcByteNo and shift it to tgtBitNo
if tgtByteNo >= self.Length:
sys.exit('Signal does not fit into message!')
tmp = sig.Data[srcByteNo]
tmp = tmp >> srcBitNo
tmp = tmp & 0x01
if tmp == 1: # the bit shall be set
self.Data[tgtByteNo] |= (1 << tgtBitNo)
else: # the bit shall be cleared
self.Data[tgtByteNo] &= ~(1 << tgtBitNo)
# increment the counters
srcBitNo += 1
if srcBitNo >= 8: # on bit counter overflow, increment the byte counter and reset the bit counter
srcBitNo = 0
srcByteNo += 1
tgtBitNo += 1
if tgtBitNo >= 8:
tgtBitNo = 0
tgtByteNo += 1
'''
Takes the CAN message data and decomposes it into its signals.
This method is basically the reversion of the method composeData.
'''
def decomposeData(self):
for sigKey in self.Signals:
sig = self.Signals[sigKey]
tgtBegin = 0 # writing the target data (to the signal) always starts at the first byte
srcBegin = sig.Begin # where the target data is in the message is defined in the Begin field of the CanSignal object. Unit: bits
tgtByteNo = tgtBegin/8 # will be 0 if tgtBegin == 0
tgtBitNo = tgtBegin%8 # will be 0 if tgtBegin == 0
srcByteNo = srcBegin/8 # get the byte and bit numbers
srcBitNo = srcBegin%8 # for the source (the CanMessage object) array
for i in range(0, sig.Length):
# copy the source data bits into the target
if srcByteNo >= self.Length:
sys.exit('Signal data not in message (message too short)')
tmp = (self.Data[srcByteNo] & (1<<srcBitNo))
if tmp > 0: # the bit shall be set
sig.Data[tgtByteNo] |= (1<<tgtBitNo)
else: # the bit shall be cleared
sig.Data[tgtByteNo] &= ~(1<<tgtBitNo)
# increment the counters
srcBitNo += 1
if srcBitNo >= 8: # on bit counter overflow, increment the byte counter and reset the bit counter
srcBitNo = 0
srcByteNo += 1
tgtBitNo += 1
if tgtBitNo >= 8:
tgtBitNo = 0
tgtByteNo += 1
self.Signals[sigKey] = sig
'''
Calculate the CRC checksum over the whole message.
The VW implementation is a very simple implementation that cannot really be called a CRC: They simply do a bitwise
XOR on the message data.
If this is true for all checksums is not certain! Has been tested for mMotor_5 and mMotor_6 only!
'''
#def calculateCRC(self):
# #crc = Crc(width=8, poly=0x01, reflect_in = False, reflect_out = False, xor_in = 0xff, xor_out = 0xff) # configure the crc calculator according to the VW parameters
# #self.composeData()
# #data = self.Data.tostring()
# #my_crc = crc.bit_by_bit_fast(data)
# #return my_crc
#
# my_crc = 0;
# for i in range(len(self.Data)):
# my_crc ^= self.Data[i]
#
# return my_crc