c# - Calculate CRC 15 for CAN BUS -
i need calculate crc checksum can bus.
scenario:
my input looks following (where x
either 1
or 0
, *
marks multiple times x
, |
marks section , -
change of input method, lb
is label
, tb
textbox
, cb
combobox
):
lb
: 0tb
: 11xcb
: xcb
: xlb
: 1tb
: 4x =>convert.tostring(8-64 / 8, 2).padleft(4, '0');
tb
: 8-64x, =>8-64 % 8 == 0
tb
: 15x =>crc of above
lb
: 1lb
: 11lb
: 1111111lb
: 111
which returns layout:
0|11*x-x|x-1-4*x|64*x|15*x-1|11|1111111|111
example:
00101010101000100100101010100101010(missing 15*x crc sum)1111111111111
this string processed following string extension, maximal 5 equal digits follow each other:
public static string correct4crc(this string s) { return s.replace("00000", "000001").replace("11111", "111110"); }
after following method returns divisor:
public static biginteger createdivisor(string s) { var = biginteger.parse(s); var d = biginteger.pow(i, 15) + biginteger.pow(i, 14) + biginteger.pow(i, 10) + biginteger.pow(i, 8) + biginteger.pow(i, 7) + biginteger.pow(i, 4) + biginteger.pow(i, 3) + 1; return d; }
the problem i've got part ^
:
public static string crc(this string s) { var dd = s.correct4crc(); var dr = dd.createdivisor().tostring(); int drl = dr.length; var d = dd.substring(0, drl).createdivisor(); var f = d ^ dr.createdivisor(); var p = true; while (p) { d = dd.substring(0, drl).createdivisor(); f = d ^ dr.createdivisor(); p = d > dd.createdivisor(); } return f.tostring(); }
i know might closed asking code, please bear me don't it. problem is, there no real documentation helped me figuring out.
anyway, if know 1 doc, solves problem please add comment. i'll check out , close answer myself if it.
i think bitstuffing wrong (the replacement of 00000 000001 , of 11111 111110), because doesn't handle avalanche replacements... 0000011110000 becomes 0000011111000001.
here http://blog.qartis.com/can-bus/ there seems example. page linked http://ghsi.de/crc/index.php?polynom=1100010110011001&message=2aa80 generates c code calculating crc-15.
// 0000011110000 becomes 0000011111000001 public static string bitstuff(string bits) { stringbuilder sb = null; char last = ' '; int count = 0; (int = 0; < bits.length; i++) { char ch = bits[i]; if (ch == last) { count++; if (count == 5) { if (sb == null) { // maximum length equal length of bits // plus 1 length 5, 2 length 9, 3 length 13... // because maximum expanion // 00000111100001111... or 11111000011110000... sb = new stringbuilder(bits.length + (bits.length - 1) / 4); sb.append(bits, 0, i); } sb.append(ch); last = ch == '0' ? '1' : '0'; sb.append(last); count = 1; continue; } } else { last = ch; count = 1; } if (sb != null) { sb.append(ch); } } return sb != null ? sb.tostring() : bits; } // taken http://ghsi.de/crc/index.php?polynom=1100010110011001&message=2aa80 public static string crc15(string bits) { var res = new char[15]; // crc result var crc = new bool[15]; (int = 0; < bits.length; i++) { bool doinvert = (bits[i] == '1') ^ crc[14]; // xor required? crc[14] = crc[13] ^ doinvert; crc[13] = crc[12]; crc[12] = crc[11]; crc[11] = crc[10]; crc[10] = crc[9] ^ doinvert; crc[9] = crc[8]; crc[8] = crc[7] ^ doinvert; crc[7] = crc[6] ^ doinvert; crc[6] = crc[5]; crc[5] = crc[4]; crc[4] = crc[3] ^ doinvert; crc[3] = crc[2] ^ doinvert; crc[2] = crc[1]; crc[1] = crc[0]; crc[0] = doinvert; } // convert binary ascii (int = 0; < 15; i++) { res[14 - i] = crc[i] ? '1' : '0'; } return new string(res); }
and then:
string bits = "0101010101010000000"; // example data string crc = crc15(bits); bits = bits + crc; bits = bitstuff(bits); bits += '1'; // crc delimiter bits += 'x'; // ack slot todo bits += '1'; // ack delimiter bits += "1111111"; // eof
note have put value ack slot
Comments
Post a Comment