Connecting Tech Pros Worldwide Help | Site Map

Can someone help me with this serial protocol.

Newbie
 
Join Date: Jul 2009
Posts: 10
#1: Jul 29 '09
I am making a link between 2 systems. They communicate over a serial link. I know the protocol and all the commands.
However I can’t figure out what the “dn” is supposed to mean. Is it the number of d’s?
I also don’t know what the crc.high and crc.low is all about. I know that the crc is a checksum and I know how to calculate it but I don’t know what the high and low are.

JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#2: Jul 29 '09

re: Can someone help me with this serial protocol.


dn is the last byte of data; d1 is the first data byte, d2 is the second data byte and when you have n bytes of data, dn is the last data byte. crc.high and crc.lo are the hi and lo bytes of the 16 bit wide crc number (16 bits == 2 bytes).

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#3: Jul 29 '09

re: Can someone help me with this serial protocol.


Thank you man, you are my hero.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#4: Jul 29 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

Thank you man, you are my hero.

You're welcome of course; you still have to read the specification because from that picture I can't tell whether or not the 'cmd' byte (or the leading/trailing bytes) is/are included in the crc value.

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#5: Jul 30 '09

re: Can someone help me with this serial protocol.


Yes, they are. They are calculated in way I don’t rely understand. It says I have to divide the crc by 0x147A. But is crc the sum of the command and the trailing bytes or zero? I have included a screenshot of the calculation.

I’m not really used to the level of technical programming. I’m more involved in making windows apps and web apps. Though I really like this technical stuff, it’s just hard to understand without the proper education.

JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#6: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

Yes, they are. They are calculated in way I don’t rely understand. It says I have to divide the crc by 0x147A. But is crc the sum of the command and the trailing bytes or zero? I have included a screenshot of the calculation.

I’m not really used to the level of technical programming. I’m more involved in making windows apps and web apps. Though I really like this technical stuff, it’s just hard to understand without the proper education.

You just have to initialize the crc value to 0x147a according to that picture. Then rotate it and do the funny add as described in step 2c. Perform those steps for the cmd byte and all the d bytes.

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#7: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by JosAH View Post

You just have to initialize the crc value to 0x147a according to that picture. Then rotate it and do the funny add as described in step 2c. Perform those steps for the cmd byte and all the d bytes.

kind regards,

Jos

So I code the initial crc like this :

Expand|Select|Wrap|Line Numbers
  1. uint crc = 0x147A;           
  2. crc = crc << 1;
  3. crc ^= 0xFFFF;
  4.  
Then the example they gave in 2c would be :

Expand|Select|Wrap|Line Numbers
  1. uint test = 0xFEDC; // crc
  2. test += GetHighLow(test.ToString("X")).high; //crc.high
  3. test += 0xA9; // b
  4.  
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#8: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

So I code the initial crc like this :

Expand|Select|Wrap|Line Numbers
  1. uint crc = 0x147A;           
  2. crc = crc << 1;
  3. crc ^= 0xFFFF;
  4.  

Not really; they want to rotate the crc value; you're just shifting it to the left one bit; change the second line to:

Expand|Select|Wrap|Line Numbers
  1. crc= (crc<<1)|((crc>>15)&1);
  2.  
this code snippet shifts the crc to the left one bit and 'or's bit 15 in as the new lo bit (bit #0); this mimics a rotate operation.

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#9: Jul 30 '09

re: Can someone help me with this serial protocol.


Thanks for finding that error in my code.
I think there is still something wrong with my calculation. In the example below I’m sending a command that requires 4 bytes of data. The protocol is designed to not give a reply if there is something wrong with the crc.

I confirmed that communicating through code is working when I use the system in monitoring mode. So the cable and the communication setting are correct. It has to be something in this piece of code.


Expand|Select|Wrap|Line Numbers
  1. private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             serialPort.Open();
  4.  
  5.             byte[] versturen = new byte[11];
  6.  
  7.             // Start
  8.             versturen[0] = 0xFE;
  9.             versturen[1] = 0xFE;
  10.  
  11.             // Command
  12.             versturen[2] = 0xE0;
  13.  
  14.             // 4 byte data
  15.             versturen[3] = 0x12;
  16.             versturen[4] = 0x34;
  17.             versturen[5] = 0x5F;
  18.             versturen[6] = 0xFF;
  19.  
  20.             // crc
  21.             versturen[7] = CalcCrc(0xE0 | 0x12 | 0x34 | 0x5F | 0xFF).high;
  22.             versturen[8] = CalcCrc(0xE0 | 0x12 | 0x34 | 0x5F | 0xFF).low;
  23.  
  24.             // End
  25.             versturen[9] = 0xFE;
  26.             versturen[10] = 0x0D;
  27.  
  28.             serialPort.Write(versturen, 0, versturen.Length);
  29.             MessageBox.Show(ReadData().ToString());
  30.             serialPort.Close();
  31.         }
  32.  
  33. private byte Hex(string hex)
  34.         {
  35.             return byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
  36.         }
  37.  
  38.         private HighLow CalcCrc(params byte[] list)
  39.         {
  40.             uint crc = 0x147A; // crc
  41.  
  42.             foreach (byte b in list)
  43.             {
  44.                 crc = (crc << 1) | ((crc >> 15) & 1); ; // crc left rotation
  45.                 crc ^= 0xFFFF; // crc / 0xFFFF
  46.  
  47.                 crc += GetHighLow(crc.ToString("X")).high;
  48.                 crc += b;
  49.             }
  50.  
  51.             return GetHighLow(((crc.ToString("X")).Substring((crc.ToString("X").Length - 4), 4)));
  52.         }
  53.  
  54.         private HighLow GetHighLow(string format)
  55.         {
  56.             return new HighLow(Hex(format.Substring(0, 2)),
  57.                 Hex(format.Substring(2, 2)));
  58.         }
  59.  
  60.         private struct HighLow
  61.         {
  62.             public HighLow(byte high, byte low)
  63.             {
  64.                 this.high = high;
  65.                 this.low = low;
  66.             }
  67.  
  68.             public byte high;
  69.             public byte low;
  70.         }
  71.  
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#10: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

Expand|Select|Wrap|Line Numbers
  1.             // crc
  2.             versturen[7] = CalcCrc(0xE0 | 0x12 | 0x34 | 0x5F | 0xFF).high;
  3.             versturen[8] = CalcCrc(0xE0 | 0x12 | 0x34 | 0x5F | 0xFF).low;
  4.  

What do these lines do? If this is Java or C# the parameter (a single one!) certainly doesn't result in an array of bytes; the | operator bitwise-or's its operands which most certainly is not what you want.

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#11: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by JosAH View Post

What do these lines do? If this is Java or C# the parameter (a single one!) certainly doesn't result in an array of bytes; the | operator bitwise-or's its operands which most certainly is not what you want.

kind regards,

Jos

Changed it to :
Expand|Select|Wrap|Line Numbers
  1. // crc
  2.             versturen[7] = CalcCrc(new byte[] {0xE0, 0x12, 0x34, 0x5F, 0xFF}).high;
  3.             versturen[8] = CalcCrc(new byte[] {0xE0, 0x12, 0x34, 0x5F, 0xFF}).low;
But still no result.
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#12: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

Changed it to :

Expand|Select|Wrap|Line Numbers
  1. // crc
  2.             versturen[7] = CalcCrc(new byte[] {0xE0, 0x12, 0x34, 0x5F, 0xFF}).high;
  3.             versturen[8] = CalcCrc(new byte[] {0xE0, 0x12, 0x34, 0x5F, 0xFF}).low;
But still no result.

Next I don't understand what your line #47 does:

Expand|Select|Wrap|Line Numbers
  1.  crc += GetHighLow(crc.ToString("X")).high;
  2.  
Better change that to:

Expand|Select|Wrap|Line Numbers
  1. crc+= (crc>>8)&0xff;
  2.  
That adds the high byte of the crc to the crc value itself, just as your documentation says so.

kind regards,

Jos
Newbie
 
Join Date: Jul 2009
Posts: 10
#13: Jul 30 '09

re: Can someone help me with this serial protocol.


It finally worked. I found out that my ReadData() method had a check for bytes in the buffer which failed and told me the buffer was empty. If is just start reading I receive a reply.

I thank you very much Jos. I could not have begun to crack this without your help.

BTW. Can I assume that if
Expand|Select|Wrap|Line Numbers
  1. (crc>>8)&0xff
get me the high,
Expand|Select|Wrap|Line Numbers
  1. (crc<<8)&0xff 
gives me the low?
JosAH's Avatar
Expert
 
Join Date: Mar 2007
Posts: 10,611
#14: Jul 30 '09

re: Can someone help me with this serial protocol.


Quote:

Originally Posted by kryptonite88 View Post

It finally worked. I found out that my ReadData() method had a check for bytes in the buffer which failed and told me the buffer was empty. If is just start reading I receive a reply.

I thank you very much Jos. I could not have begun to crack this without your help.

BTW. Can I assume that if

Expand|Select|Wrap|Line Numbers
  1. (crc>>8)&0xff
get me the high,
Expand|Select|Wrap|Line Numbers
  1. (crc<<8)&0xff 
gives me the low?

Nope, the first expression shifts the crc value 8 bits to the right and masks everything away except for the lower 8 bits (that's the value 0xff). So if you want to keep just the lo byte there's no need to shift anything, just mask everything except for the lowest eight bits away; like this:

Expand|Select|Wrap|Line Numbers
  1. int lo= crc&0xff;
  2.  
kind regards,

Jos
Reply