|
|
View previous topic :: View next topic |
Author |
Message |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Nov 16, 2012 5:27 pm |
|
|
Quote: | While trying to understand the code I found I could replace the two rlcf with one rlncf on a PIC18. | Nice find!
I have updated my code at the start of this topic to include this improvement. |
|
|
downybear
Joined: 18 Nov 2012 Posts: 1
|
Poly change impossible? |
Posted: Mon Nov 19, 2012 2:50 am |
|
|
Hi,
I have found this discussion with very elegant solution for CRC16 for embedded projects.
I would change poly to CRC16-ARC - 0x8005.
I think it should be for 0x8005:
Code: | crc = (crc << 8) ^ (x << 15) ^ (x << 2) ^ x; |
instead of 0x1021
Code: | crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ x; |
Additionally original CRC16-ARC starts from crc=0x0000 and needs bits reflecting in input bytes and reflecting crc bits on output (0b11010010 -> 0b01001011).
I have a set of W. Erhardt applications (SRP, TCRC) as a reference calculations but I can't get proper CRC with this algorithm after poly change.
I have written small app in Delphi using code presented here and I have got same results like in PIC18 environment - good CRC calculations for 0x1021 and bad calculations for 0x8005 poly. To do bits reflecting I have used functions copied from W. Erhardt applications.
My mistakes or ..... algorithm for 0x1021 only? - I do not want to believe..
Any ideas?
Regards
Mariusz
One hour later...
I have repeated some steps of my discovering and now I have found notice from the Ashley Roll:
Quote: |
* I've used the Standard CCITT CRC16 polynomial as this "standard"
* doesn't use any of the bit reflection that confuses the implementation.
* This polynomial is 0x1021 but you could use any you like.
|
Full text is here:
http://www.digitalnemesis.com/info/codesamples/embeddedcrc16/gentable.c
So it means that when bits are reflecting something can go wrong.
Looking for another solutions I have found:
http://miscel.dk/MiscEl/CRCcalculations.html
There are some Pascal examples of table and non-table CRC calculations.
I have checked immediately function CRC16 bit, inverted/reversed/reflected and I have got good result.
I have translated it to C and it works in PIC18F environment as well
Here is the final, not optimized yet code:
Code: |
unsigned int Calc_CRC_C_ARC(unsigned char *Buffer, unsigned int Len, unsigned int crc_seed)
{
crc = crc_seed;
while(Len--)
{
bufdat = *Buffer++;
crc = crc ^ bufdat;
for (i = 0;i < 8; i++)
{
if ((crc & 0x0001) !=0)
{
// Expected poly should be bits reflected so 0xA001 used instead of 0x8005;
crc = (crc >> 1) ^ 0xA001;
}
else
{
crc = crc >> 1;
}
}
}
// Swapping final CRC nibbles
crc = (crc >> 8) | (crc << 8);
printf("CRC ARC: Seed: %.4x; Val: %.4x\r\n",crc_seed, crc);
return crc;
}
|
Now I will optimize the code and check if this is fast enough for me, if not I will go to assembler.
I hope that it can be useful for somebody
Regards
Mariusz |
|
|
dawel
Joined: 18 Oct 2017 Posts: 1
|
|
Posted: Wed Oct 18, 2017 7:57 am |
|
|
Hi,
I have used this code to determine the crc16 for a PIC 24FJ128GA204.h
but it get the false crc. Can anybody tell me what's wrong ?
http://www.ccsinfo.com/forum/viewtopic.php?t=24977
Code: |
int16 crc_1021(int16 old_crc, int8 data)
{
int16 crc;
int16 x;
x = make8(old_crc,1) ^ data; //x = ((old_crc>>8) ^ data) & 0xff;
x ^= x>>4;
crc = (old_crc << 8) ^ (x << 12) ^ (x <<5) ^ x;
//crc &= 0xffff;
return crc;
}
|
I want to build the crc of this char '*'
Code: |
const int16 CRC_startwert=0xffff
CRC_Calc_X = CRC_startwert;
CRC_Calc_X = crc_1021(CRC_Calc_X,'*');
|
THX |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 19, 2017 10:16 am |
|
|
That routine is written for the PCM and/or PCH compilers. In those
compilers, the default for integer data types is unsigned.
However, in the PCD compiler (which you have), the default is signed.
So I suggest that you change all variable declarations in the CRC routine
and in your program to 'unsigned'. Then it has a chance to work.
Example:
Quote: |
unsigned int16 crc_1021(unsigned int16 old_crc, unsigned int8 data)
{
unsigned int16 crc;
unsigned int16 x;
|
And do it everywhere else where there is a variable declaration.
Edit: Dawel reports in a PM that this has resolved his problem. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|