CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

CRC module

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

CRC module
PostPosted: Wed Sep 10, 2014 4:23 am     Reply with quote

I'm struggling all morning with the CRC commands of the PIC24. The hardware module plus CCS commands make it seem like child play but it's never as easy as it seems, isn't it?
I am trying to implement the following CRC scheme:
CRC16-CCITT, poly=0x1021 init=0xFFFF (x16 + x12 + x5 + 1)
To test, I get the data and result from online calculators such as http://www.lammertbies.nl/comm/info/crc-calculation.html
Let's try just the character 'Z' (0x5A). The calculator shows a result of 0x1A4F.

Code:

//PIC24FJ64GA308
//compiler 5.026
   int16 rslt;

   setup_crc(16,12,5); // CRC16-CCITT, poly=0x1021 init=0xFFFF (x16 + x12 + x5 + 1)
   crc_init(0xFFFF);
   rslt=crc_calc8('Z');

The result I get is 0xE1AA

I've been fiddling with this all morning and I think it's better as a random number generator Razz
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 4:59 am     Reply with quote

I don't think you are handling the width right.

If you look at the crc_calc description, it says the input width defaults to the output width. You want to calculate a 16bit CRC, from an 8bit value, so I'd expect to have to use:

rslt=crc_calc16('Z',8);

May well be wrong, but worth a try. Haven't got anything running a PIC24 handy at the moment to have a play!....

It'd help if the example existed.... Crying or Very sad
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Wed Sep 10, 2014 5:07 am     Reply with quote

Hi Ttelmah!
crc_calc16('Z') returns 0x1D55 . My guess was that calc8/16/32 defines the input data size.
The length parameter talks about processing buffers. I found that
Code:
   for(i=0;i<10;i++) {
      rslt=crc_calc8(buf[i]);
   }

and
Code:
   rslt=crc_calc8(buf,10);


are equivalent.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 9:03 am     Reply with quote

The calcx functions, specify _both_ the input size and the output size.
So for calc16, it generates a 16bit CRC from 16bit data. You want a 16bit CRC from 8bit data, so should have to use the calc16 as I show. Or as:

calc16((int16)'Z')

They specifically say the width value is in bits, so it should be 8 if used.

However your loop example, throws doubt upon everything....

I suggest you ask CCS to post an example. They refer to an example, but it doesn't exist, which is silly....

There is also the option CRC_LITTLE_ENDIAN, which will change the order of the result.

The other thing to do, would be to look at the generated assembler, to see if you can work out how they are using the hardware module.
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Wed Sep 10, 2014 9:28 am     Reply with quote

Quote:
The other thing to do. would be to look at the generated assembler, to see if you can work out how they are using the hardware module.

I'd rather commit suicide than go into non-working assembler code that someone else wrote for CRC... LOL!!! But thanks.

I found this non-efficient un-cool code (22.5us per byte on 32MHz PIC24) which is 'good enough' and tested. I'd still rather use a more elegant HW solution.
It is based on http://stackoverflow.com/questions/7961964/android-crc-ccitt

Enjoy...

Code:

//CRC16-CCITT, poly=0x1021 init=0xFFFF (x16 + x12 + x5 + 1)
// based on  http://stackoverflow.com/questions/7961964/android-crc-ccitt
int16 crc;

void doCRC(byte ch) {
   short bt,c15;
   byte ii;

       for (ii = 0; ii < 8; ii++) {
           bt=bit_test(ch,7-ii);
           //bt = ((b   >> (7-ii) & 1) == 1);
           c15=bit_test(crc,15);
           //c15 = ((crc >> 15    & 1) == 1);
           crc <<= 1;
           if (c15^bt) crc ^= 0x1021;
        }
}
///////////////////////////////////////
void main() {
    byte i,ch;
    crc=0xFFFF;
   
    for(i=0;i<10;i++) {
        ch=getc();
        doCRC(ch);
    }
    // crc contains 16-bit result.
}


Last edited by guy on Thu Sep 11, 2014 1:37 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Wed Sep 10, 2014 11:12 am     Reply with quote

There is a software CRC routine with the compiler. Look at ex_crc.c and the driver in crc.c

The actual assembler for the hardware routine is only about 20 lines. Not exactly large. Unfortunately the software simulator in MPLAB doesn't emulate the peripheral correctly, otherwise I'd see what it does.
guy



Joined: 21 Oct 2005
Posts: 297

View user's profile Send private message Visit poster's website

PostPosted: Thu Sep 11, 2014 1:35 am     Reply with quote

Quote:
There is a software CRC routine with the compiler. Look at ex_crc.c and the driver in crc.c

I did. The code was a little too complicated... Anyway you saw the code I posted - same [un]efficiency but very straightforward.
Thanks!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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