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