CRC confusion (solved)
ManAtWork
Posts: 2,176
I know how to calculate a CRC and I've even already managed to write a CRC16 function using the CRCNIB instruction. However, I'm just a little confused how it is properly used.
I have a packet of 12 bytes I send over a serial line, 10 bytes payload and 2 bytes CRC. I calculate the CRC and write it to the end of the buffer, then I send out all 12 bytes.
My problem is that the other side is not a propeller but an ARM chip. I can't receive the first 10 bytes seperately, calculate the CRC and compare it to the last 2 bytes. I have to receive all the 12 bytes continously and calculate the CRC over all 12 bytes. (receiving has to be done with DMA in a single block because the ARM has not enough power to bit bang single bytes)
I know that there is some trick to prepare the CRC of the sender in such a way that the receiver will see a CRC of zero when he includes the sender CRC in the calculation. Unfortunatelly, I have forgotten how this works. I think, I have to add some padding bytes or use a different start value... Anybody knows what to do?
I have a packet of 12 bytes I send over a serial line, 10 bytes payload and 2 bytes CRC. I calculate the CRC and write it to the end of the buffer, then I send out all 12 bytes.
My problem is that the other side is not a propeller but an ARM chip. I can't receive the first 10 bytes seperately, calculate the CRC and compare it to the last 2 bytes. I have to receive all the 12 bytes continously and calculate the CRC over all 12 bytes. (receiving has to be done with DMA in a single block because the ARM has not enough power to bit bang single bytes)
I know that there is some trick to prepare the CRC of the sender in such a way that the receiver will see a CRC of zero when he includes the sender CRC in the calculation. Unfortunatelly, I have forgotten how this works. I think, I have to add some padding bytes or use a different start value... Anybody knows what to do?
Comments
I think you may look at the source code for xmodem and zmodem protocols where these tricks are used.
As far as I remember (and looking at some source code), for CRC16 just initialize it at 0 and the final CRC will be zero as well.
Here is an excerpt of a ZModem routine (see the Z_UpdateCRC calls):
Hope this helps.
Here's the code for sending a packet and doing crc for prop1:
This gave me the following CRC values (after each byte):
Now, I placed the calculated CRC into the buffer ... and ran the test again, this time with all 12 bytes. The result is
But then I remembered that the last time I programmed an YModem protocol was on a big endian machine (Commodore Amiga with Motorola CPU).
I tried swapping the byte order. And... guess what... now it also works on the propeller!
So that's the trick: The byte order must match the shifting direction of the CRC generator. Shifting left means high byte first.
So, although your code example didn't help me immediately it pointed me in the right direction. Thanks!
You need to work out what to start with (load your crc variable with initially), and you need to work out if you need to reverse the bits. Once you work out these two things, the crc should fall into place. There is an old P2 thread somewhere where I worked this out but it may just be simpler to look for the website.