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 support@ccsinfo.com

CRC
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kondra



Joined: 23 Sep 2003
Posts: 4

View user's profile Send private message

CRC
PostPosted: Tue Sep 23, 2003 6:23 am     Reply with quote

HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.

I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources



THX
_________________
the next guy has always a better life
TSchultz



Joined: 08 Sep 2003
Posts: 66
Location: Toronto, Canada

View user's profile Send private message

PostPosted: Tue Sep 23, 2003 7:32 am     Reply with quote

There are a variety of methods used for error detection in a data stream, and as the method gets more reliable, the complexity also increases. What you want to use will depend on your actual application, if you can tolerate a bad packet, and how much code/processor you want to allocate to the task.

For short packets a simple XOR addition works well and requires very little overhead. The reliability is even further improved if the packet is framed. I have a simple protocol I use for multi-drop application that is as follows;

BOF, ID, LEN, ... DATA ... FCS, EOF

BOF = Begining of frame marker
ID = device ID to address
LEN = number of data bytes in packet
DATA = variable number of data bytes, 0 - 60
FCS = XOR addition of ID, LEN, and DATA bytes
EOF = End of frame marker

Here I use only a simple XOR addition, but also the framing must be correct and the ID must also be correct. Using this method I can calculate the FCS on the fly and when I include the received FCS I should have a zero value if the packet is good. In addition I time-out if I have not recieved a full packet within a set amount of time. My receive and transmit routines are interrupt based, and upon reciept of a valid pakcet I set a flag that my main routines sees and the packet is then decoded and handled.

CRC usually involves a more complicated polynomial method but results in better bit error detection. A quick google search will yield a number of sources for such routines.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: CRC
PostPosted: Tue Sep 23, 2003 8:05 am     Reply with quote

kondra wrote:
HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.

I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources

THX


This works with MODBUS packet formating. This is as highly optimized as I could make it. If you improve on this please be so kind as to post your work. You can read more at www.modbus.org

Code:


#inline                                                     // Inline code runs faster
void Make_Check_CRC(void)                                   // This function can be used to create or check CRC
{  good_crc = 0;                                            // Assume this packet is bad
   crcacc = 0xFFFF;                                         // Initialize the CRC accumuliator
   PacketIndex = 0;                                         // First byte indexed as zero
   while(PacketIndex < PacketSize)                          // Use all byte except CRC
   {  crcdata = PacketBuffer[PacketIndex];                  // Use direct addressing on copy of data value
      crcacc_lo = crcacc_lo^crcdata;
      for(c=8;c>0;c--)                                      // Process the data bits
      {  if(LS_BIT_crcacc)                                  // Should XOR be performed
         {  crcacc = crcacc >> 1;                           // Shift CRC 1 bit right load high with 0
            crcacc = crcacc^0xA001;                         // then XOR
         }
         else
         {  crcacc = crcacc >> 1;                           // Shift CRC 1 bit right load high with 0
         }
      }                                                     // Processed all bits of byte
      PacketIndex++;                                        // Advance index to the next byte
   }                                                        // Solved values for CRC
   PacketSize=PacketSize+1;                                 // Index CRC_hi
   if((crcacc_lo == PacketBuffer[PacketIndex]) && (crcacc_hi == PacketBuffer[PacketSize]))
      good_crc = 1;                                         // The packet recieved was good
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Sep 23, 2003 9:18 am     Reply with quote

Maybe this will shave a couple of instructions off

Code:


#inline                                                     // Inline code runs faster
void Make_Check_CRC(void)                                   // This function can be used to create or check CRC
{  good_crc = 0;                                            // Assume this packet is bad
   crcacc = 0xFFFF;                                         // Initialize the CRC accumuliator
   PacketIndex = 0;                                         // First byte indexed as zero
   while(PacketIndex < PacketSize)                          // Use all byte except CRC
   {  crcdata = PacketBuffer[PacketIndex];                  // Use direct addressing on copy of data value
      crcacc_lo = crcacc_lo^crcdata;
      for(c=8;c>0;c--)                                      // Process the data bits
      { 
        crcacc = crcacc >> 1;                           // Shift CRC 1 bit right load high with 0
        if(LS_BIT_crcacc)                                  // Should XOR be performed
         crcacc = crcacc^0xA001;                         // then XOR
      }                                                     // Processed all bits of byte
      PacketIndex++;                                        // Advance index to the next byte
   }                                                        // Solved values for CRC
   PacketSize=PacketSize+1;                                 // Index CRC_hi
   if((crcacc_lo == PacketBuffer[PacketIndex]) && (crcacc_hi == PacketBuffer[PacketSize]))
      good_crc = 1;                                         // The packet recieved was good
}
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Tue Sep 23, 2003 10:08 am     Reply with quote

I forgot to include these variable declarations.
Code:

int16 crcacc;                                               // CRC accumuliator
#byte crcacc_lo = crcacc                                    // Alias name for CRC accumuliator low byte
#byte crcacc_hi = crcacc + 1                                // Alias name for CRC accumuliator high byte
#bit LS_BIT_crcacc = crcacc.0                               // Alias name for bit zero of CRC accumuliator

crcacc can't shift before checking the least bit because it gets shifted out. Sorry for the confusion. I got all excited for a second because this routine eats a lot of time on an irregular interval. Anything I can shave off of this allows the system tick to run faster. I though about trying to multiplex the CRC calculations but it was more than I could manage to solve in an elegant manner.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Sep 23, 2003 10:29 am     Reply with quote

Sorry, I didn't look that closely at the test expression. Have you ever thought about using a lookup table? Here are some code snippets from some XYModem file transfer routines. It creates a ram based table but this could easily be put into a rom table.

Code:

/****************************************************************************
    InitCRC16 pre-computes a table of constants, using a bitwise algorithm.
    These constants allow fast computation of the CRC.

    CCITT CRC16 generating polynomial is x^16+x^12+x^5+1, with
    binary representation 0x11021.  The leading term is implied.
*/
static unsigned int crcTable[256];

static void InitCRC16(void)
{
    static int crcDone = 0; /* Only compute it once */
    unsigned i, j, crc;

    if (crcDone) return;
    for(i=0; i <256; i++) {
        crc = (i << 8);
        for(j=0; j < 8; j++)
            crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
        crcTable[i] = crc & 0xffff;
    }
    crcDone = 1;
}

static int XYSendPacket(XYMODEM *pXY, BYTE *pBuffer, int length)
{
    int i;
    int crc = 0;           /* Accumulate CRC for data and padding */
    int checksum = 0;     /* Accumulate checksum for data and padding */

    ASSERT(pBuffer);
    ASSERT(pXY);
    /* Compute the check value now, so that we don't pause in the middle
       of sending to do it. */
    if (pXY->crc.enabled) {
        for (i=0; i<length; i++)
            crc = crcTable[((crc >> 8) ^ pBuffer[i]) & 0xFF] ^ (crc << 8);
        for (; i<128; i++)
            crc = crcTable[((crc >> 8) ^ SUB) & 0xFF] ^ (crc << 8);
        if (i > 128)
            for (; i<1024; i++)
                crc = crcTable[((crc >> 8) ^ SUB) & 0xFF] ^ (crc << 8);
    } else {
        for (i=0; i<length; i++)  checksum += pBuffer[i];
        if (i > 128)              checksum += (1024 - i) * SUB;
        else                      checksum += (128 - i) * SUB;
    }

    /* Clear any garbage from receive queue */
    StsRet(XYGobble(pXY,0));
    /* start sending the data */
    if (length <= 128)  StsRet(XYSendByte(pXY, 0x01));
    else                StsRet(XYSendByte(pXY, 0x02));

    StsRet(XYSendByte(pXY, (BYTE)pXY->packetNumber));
    StsRet(XYSendByte(pXY, (BYTE)~pXY->packetNumber));

    /* Send the data, pad to 128 or 1024 bytes */
    StsRet(XYSendBytes(pXY, pBuffer, length));
    for (i=length; i < 128; i++) StsRet(XYSendByte(pXY,SUB));
    if (i > 128) for (; i<1024; i++) StsRet(XYSendByte(pXY, SUB));

    /* Send the check value */
    if (pXY->crc.enabled) {
        StsRet(XYSendByte(pXY, (BYTE)(crc >> 8)));
        StsRet(XYSendByte(pXY, (BYTE)crc));
    } else {
        StsRet(XYSendByte(pXY, (BYTE)checksum));
    }
    StsRet(XYWaitForSentBytes(pXY));
    return xyOK;
}

static int XYReceivePacket(XYMODEM *pXY, int *pPacketNumber,
                           BYTE *pBuffer, long *pLength)
{
    BYTE  startOfPacket = 0;
    BYTE  packet = 0;
    BYTE  packetCheck = 0;

    ASSERT(pPacketNumber);
    ASSERT(pBuffer);
    ASSERT(pXY);
    /* This loop searches the incoming bytes for a valid packet start. */
    /* This reduces our sensitivity to inter-packet noise. */
    /* We also check here for EOT and CAN packets. */
    StsRet(XYReadBytesWithTimeout(pXY,pXY->timeout,&packetCheck,1));
    if (packetCheck == EOT) return xyEOT;
    do {
        startOfPacket = packet; packet = packetCheck;
        StsRet(XYReadBytesWithTimeout(pXY,pXY->timeout,&packetCheck,1));
        if ((packetCheck == CAN) && (packet == CAN)) return StsWarn(xyFailed);
    } while (  ( (startOfPacket != 0x01) && (startOfPacket != 0x02) )
            || ( ((packet ^ packetCheck) & 0xFF) != 0xFF ) );

    /* We've received a valid packet start, receive the packet data */
    if (startOfPacket == 0x01) *pLength = 128;
    else                       *pLength = 1024;
    StsRet(XYReadBytesWithTimeout(pXY,2,pBuffer,*pLength));
    *pPacketNumber = packet;

    /* Compute the check value and compare it to the received one. */
    if (pXY->crc.enabled) {
        unsigned crc = 0;
        long length = *pLength;
        BYTE crcByte;
        unsigned rxCRC;
        while (length-- > 0)        /* Accumulate CRC */
            crc = crcTable[((crc >> 8) ^ *pBuffer++) & 0xFF] ^ (crc << 8);
        crc &= 0xFFFF;
        StsRet(XYReadBytesWithTimeout(pXY,2,&crcByte,1));
        rxCRC = (crcByte & 0xFF) << 8;
        StsRet(XYReadBytesWithTimeout(pXY,2,&crcByte,1));
        rxCRC |= (crcByte & 0xFF);
        if (crc != rxCRC) return StsWarn(xyBadPacket);
    } else {
        unsigned checksum = 0;
        BYTE receivedChecksum;
        long length = *pLength;

        while (length-- > 0)        /* Accumulate checksum */
            checksum += *pBuffer++;
        checksum &= 0xFF;
        StsRet(XYReadBytesWithTimeout(pXY,2,&receivedChecksum,1));
        if ((BYTE)checksum != receivedChecksum) return StsWarn(xyBadPacket);
    }
    pXY->crc.certain = TRUE; /* Checksum/crc mode is now known */
    if (*pLength > 128) {
        pXY->longPacket.enabled = TRUE;
        pXY->longPacket.certain = TRUE;
    }
    return xyOK;
}

jds-pic



Joined: 17 Sep 2003
Posts: 205

View user's profile Send private message

PostPosted: Wed Sep 24, 2003 8:58 am     Reply with quote

you could use the dallas onewire CRC algorithm -- quick to run, easy to implement, very few instructions, no ROM space lost, very little RAM required, no fuss, no muss, It Just Works...

Code:

int onewire_crc(int oldcrc, int newbyte) {
   // see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf

   int shift_reg, data_bit, sr_lsb, fb_bit, j;
   shift_reg=oldcrc;
   for(j=0; j<8; j++) {   // for each bit
      data_bit = (newbyte >> j) & 0x01;
      sr_lsb = shift_reg & 0x01;
      fb_bit = (data_bit ^ sr_lsb) & 0x01;
      shift_reg = shift_reg >> 1;
      if (fb_bit)
         shift_reg = shift_reg ^ 0x8c;
      }
   return(shift_reg);
}


ps, my onewire primitives library is here:
http://losdos.dyndns.org:8080/public/onewire/lib-onewire.html

regards.
jds-pic
Darren Rook



Joined: 06 Sep 2003
Posts: 287
Location: Milwaukee, WI

View user's profile Send private message Send e-mail

Re: CRC
PostPosted: Wed Sep 24, 2003 11:52 am     Reply with quote

kondra wrote:
HI ,
I'm a newbie in the PIC area and I have a problem with data transmision.

I use a network made with some 16F73 and I need to trust the data I receive .I need an algorithm easy to implement on PIC and to use few resources


XOR

Laughing
dvdb



Joined: 12 Jan 2004
Posts: 6
Location: Brussels, Belgium

View user's profile Send private message

PostPosted: Mon Jan 12, 2004 1:38 pm     Reply with quote

jds-pic wrote:
you could use the dallas onewire CRC algorithm -- quick to run, easy to implement, very few instructions, no ROM space lost, very little RAM required, no fuss, no muss, It Just Works...

Code:

int onewire_crc(int oldcrc, int newbyte) {
   // see http://pdfserv.maxim-ic.com/arpdf/AppNotes/app27.pdf

   int shift_reg, data_bit, sr_lsb, fb_bit, j;
   shift_reg=oldcrc;
   for(j=0; j<8; j++) {   // for each bit
      data_bit = (newbyte >> j) & 0x01;
      sr_lsb = shift_reg & 0x01;
      fb_bit = (data_bit ^ sr_lsb) & 0x01;
      shift_reg = shift_reg >> 1;
      if (fb_bit)
         shift_reg = shift_reg ^ 0x8c;
      }
   return(shift_reg);
}


ps, my onewire primitives library is here:
http://losdos.dyndns.org:8080/public/onewire/lib-onewire.html

regards.
jds-pic



Hi,

This a my asm implementation for the same CRC.
It is about 10X faster, 30 bytes less code and used no RAM.
It's based on http://www.dattalo.com/technical/software/pic/crc_8bit.c which exploits a pecularity of this particular polynomial described in http://pdfserv.maxim-ic.com/en/an/app27.pdf.
This allows bytewise processing without bit shifting.
I ported the algorith to asm, it turns out this can be done with no additional RAM, and with bit twiddling only in w, so its very fast and dense code.

Don't work too hard!

Code:

int calc_CRC(int* data,int byte_cntr)
{

int crc=0;

#ASM
           MOVF   DATA,W         //copy pointer to first databyte..
           MOVWF  FSR           //..to pointer register

loop:
     MOVF   INDF,W       //load w with next databyte
        xorwf crc,f        // xor with accumulated crc (accumulated crc is no longer valid now)
       movlw 0            //w will ccumulate the new crc
       btfsc crc,0
       xorlw 0x5e         //could also be iorlw
      btfsc crc,1
       xorlw 0xbc
      btfsc crc,2
       xorlw 0x61
      btfsc crc,3
       xorlw 0xc2
      btfsc crc,4
       xorlw 0x9d
      btfsc crc,5
       xorlw 0x23
      btfsc crc,6
       xorlw 0x46
      btfsc crc,7
       xorlw 0x8c
   movwf crc          //store accumulated crc
   INCF   FSR         //increment indirection register  to point to next databyte
   decfsz byte_cntr,F
   goto loop          //next databyte
                      //done, crc is in w

   movwf crc           //store in result
   

#ENDASM


return(crc);
}

_________________
Dirk Van den Berge
rrb011270



Joined: 07 Sep 2003
Posts: 51

View user's profile Send private message Yahoo Messenger

PostPosted: Tue Jan 13, 2004 6:33 pm     Reply with quote

Mabuhay!

I guess the better way to trust your data for a data communication is use the method called CRC (cyclic redundancy check). Their are many CRC method one is the basic XOR calculation, the other is to use polynomial CRC calculation.

The program code below use the XOR method to calculate checksum or CRC

Code:

void convertData_ToAscii()  // convert RFdata to ascii for serial xmit
{
   char cHexBuff[2];    // temp hex buffer
   char cDtaBuff[20];   // data buffer for time, date, log, deviceID

   // start hex to ascii conversion
   for (dummy=0; dummy<8; dummy++)
   {
      sprintf(cHexBuff,"%X",gaMemRFbuffer[dummy]);
      txbuffer[dummy*2]   = cHexBuff[0];
      txchksm ^= txbuffer[dummy*2];
      txbuffer[dummy*2+1] = cHexBuff[1];
      txchksm ^= txbuffer[dummy*2+1];
      tx_in = (dummy*2)+2;
   }

   sprintf(cDtaBuff,"%02u:%02u%02u-%02u-%02u%02u%C%04LX",
      hours,minutes,mthdays,months,y2kyrs,years,gcLogMode,deviceID);

   for (dummy=0; dummy<20; dummy++)
   {
      txbuffer[dummy+16] = cDtaBuff[dummy];
      txchksm ^= txbuffer[dummy+16];
      ++tx_in;
   }
   txbuffer[tx_in] = txchksm; // store checksum or CRC
   ++tx_in;
}



I hope this provide you a picture on CRC checking and calculation.
kypec



Joined: 20 Sep 2003
Posts: 54

View user's profile Send private message

CRC16-CCITT implementation
PostPosted: Wed Feb 18, 2004 5:20 am     Reply with quote

Here is my bit-by-bit algorithm of 16-bit CRC computation according
to CCITT specification. It's surely not as fast as table driven implementations rather it is very comprehensible.
Functions are based mainly upon the following document:
http://www.riccibitti.com/crcguide.htm

Well, here it is (tested on PIC18F452):
Code:

////////////////////////////////////////////////////////////////////////////////
//CRC16-CCITT bit-by-bit algorithm
////////////////////////////////////////////////////////////////////////////////
int16 const CRC_POLYNOMIAL=0x1021; //CRC16-CCITT specific
int16 const CRC_INIT_VALUE=0xFFFF; //CRC16-CCITT specific

union { //0xHEAD_REMAINDER_TAIL organization is useful for bit shifting operations
   int32 whole;
   struct {
      int8 tail;
      int16 remainder;
      int8 head;
   } part;
} crc16;

void one_byte_crc16(int8 new) { //process single message byte
   int8 i;
   crc16.part.tail=new; //store new message byte in the end
   for (i=0; i<8; i++) { //repeat for all 8 bits in the message byte
      crc16.whole<<=1; //new message bit goes in and MSb of remainder goes out
      if (crc16.part.head & 0x01) crc16.part.remainder^=CRC_POLYNOMIAL; //XOR if necessary
   };
}

int16 get_crc16 (int16 pointer,int8 length) { //process entire message
   int8 i;
   crc16.part.remainder = CRC_INIT_VALUE; //initialize remainder
   for (i=0;i<length;i++) one_byte_crc16(*(pointer+i)); //process all message bytes
   one_byte_crc16(0x00); //augment message = append as many zero bits
   one_byte_crc16(0x00); //as the width of polynomial is = 16
   return crc16.part.remainder;
}

int8 message[64];
int16 calculated_crc;

void main(void) {
   message[0]='1';
   message[1]='2';
   message[2]='3';
   message[3]='4';
   message[4]='5';
   message[5]='6';
   message[6]='7';
   message[7]='8';
   message[8]='9';
   calculated_crc=get_crc16(message,64);
}
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: CRC16-CCITT implementation
PostPosted: Wed Feb 18, 2004 7:51 am     Reply with quote

kypec wrote:
Here is my bit-by-bit algorithm of 16-bit CRC computation according
to CCITT specification. It's surely not as fast as table driven implementations rather it is very comprehensible.
Functions are based mainly upon the following document:
http://www.riccibitti.com/crcguide.htm

Well, here it is (tested on PIC18F452):
Code:

////////////////////////////////////////////////////////////////////////////////
//CRC16-CCITT bit-by-bit algorithm
////////////////////////////////////////////////////////////////////////////////
int16 const CRC_POLYNOMIAL=0x1021; //CRC16-CCITT specific
int16 const CRC_INIT_VALUE=0xFFFF; //CRC16-CCITT specific

union { //0xHEAD_REMAINDER_TAIL organization is useful for bit shifting operations
   int32 whole;
   struct {
      int8 tail;
      int16 remainder;
      int8 head;
   } part;
} crc16;

void one_byte_crc16(int8 new) { //process single message byte
   int8 i;
   crc16.part.tail=new; //store new message byte in the end
   for (i=0; i<8; i++) { //repeat for all 8 bits in the message byte
      crc16.whole<<=1; //new message bit goes in and MSb of remainder goes out
      if (crc16.part.head & 0x01) crc16.part.remainder^=CRC_POLYNOMIAL; //XOR if necessary
   };
}

int16 get_crc16 (int16 pointer,int8 length) { //process entire message
   int8 i;
   crc16.part.remainder = CRC_INIT_VALUE; //initialize remainder
   for (i=0;i<length;i++) one_byte_crc16(*(pointer+i)); //process all message bytes
   one_byte_crc16(0x00); //augment message = append as many zero bits
   one_byte_crc16(0x00); //as the width of polynomial is = 16
   return crc16.part.remainder;
}

int8 message[64];
int16 calculated_crc;

void main(void) {
   message[0]='1';
   message[1]='2';
   message[2]='3';
   message[3]='4';
   message[4]='5';
   message[5]='6';
   message[6]='7';
   message[7]='8';
   message[8]='9';
   calculated_crc=get_crc16(message,64);
}


If you change the for loops to count down you will have code that compiles better. It will run about ~10% faster and compile smaller slightly.

for(i=8;i>0;i--)
yellowbanana
Guest







PostPosted: Wed Feb 18, 2004 9:16 am     Reply with quote

Hi!

does someone know about a CRC that does not just detect errors, but that can also correct some of them?
Dargar



Joined: 12 Dec 2003
Posts: 25

View user's profile Send private message

PostPosted: Sat Oct 29, 2005 1:11 pm     Reply with quote

dvdb wrote:

Hi,

This a my asm implementation for the same CRC.
It is about 10X faster, 30 bytes less code and used no RAM.
It's based on http://www.dattalo.com/technical/software/pic/crc_8bit.c which exploits a pecularity of this particular polynomial described in http://pdfserv.maxim-ic.com/en/an/app27.pdf.
This allows bytewise processing without bit shifting.
I ported the algorith to asm, it turns out this can be done with no additional RAM, and with bit twiddling only in w, so its very fast and dense code.

Don't work too hard!

Code:

int calc_CRC(int* data,int byte_cntr)
{

int crc=0;

#ASM
           MOVF   DATA,W         //copy pointer to first databyte..
           MOVWF  FSR           //..to pointer register

loop:
     MOVF   INDF,W       //load w with next databyte
        xorwf crc,f        // xor with accumulated crc (accumulated crc is no longer valid now)
       movlw 0            //w will ccumulate the new crc
       btfsc crc,0
       xorlw 0x5e         //could also be iorlw
      btfsc crc,1
       xorlw 0xbc
      btfsc crc,2
       xorlw 0x61
      btfsc crc,3
       xorlw 0xc2
      btfsc crc,4
       xorlw 0x9d
      btfsc crc,5
       xorlw 0x23
      btfsc crc,6
       xorlw 0x46
      btfsc crc,7
       xorlw 0x8c
   movwf crc          //store accumulated crc
   INCF   FSR         //increment indirection register  to point to next databyte
   decfsz byte_cntr,F
   goto loop          //next databyte
                      //done, crc is in w

   movwf crc           //store in result
   

#ENDASM


return(crc);
}


This generates an 8-bit CRC code if I'm not mistaken?
How big data-sets would be practical to use before an 8-bit CRC becomes to small? 10 bytes of data? 20? 50?

-I realise this is a trade-off between how much processing power and overhead can be set aside for the CRC, and how accurately the CRC catches errors, but I do not really understand how the number of data-bytes in a packet affects this?

According to the following link
http://www.ciphersbyritter.com/ARTS/CRCMYST.HTM
a (specific) CRC-8 has a "99.29"% probability of catching errors... is this number in any way dependant on the size of the data the CRC is based on? -If not, an 8 bit crc should be enough for all but the most horrible of conditions, up to several hundred bytes.

Having no idea of what I'm doing (I'm not good with math), could I say that, if the data which the crc is performed on is 10 bytes long, then the percent chance of detecting all possible errors in the 10 bytes is 0.9929^10 = appr. 93%? If so, then whether or not 8-bit crc is enough for my application comes down to how much I trust my transmission line...


---


since the asm version is so fast, would it make sense to include 2 crc-8's in one package as opposed to a 16-bit crc? Doing it like this:
[msg header][address][ack][len][Data1][Data2][Data n][CRC1][Data n+1][Data x][CRC2]


Sorry about the long post.. hope someone is brave enough to attempt an answer to (parts) this post!
_________________
Owner of PCWH v. 3.224
Consider myself beginer\intermediate as far as CCS and Microchip PIC's goes.
Bachelor in Space Engineering and Undergraduate Masters in Space Engineering
soon to be undergrad Aerospace
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sat Oct 29, 2005 6:40 pm     Reply with quote

Quote:
This generates an 8-bit CRC code if I'm not mistaken?
Yes, this is the 8-bit CRC used by Dallas in the 1-wire protocol.
Quote:
How big data-sets would be practical to use before an 8-bit CRC becomes to small? 10 bytes of data? 20? 50?
I don't know. CRC8 is limited and I think a practical maximum block size is around 20 bytes but this isn't based on any scientific grounds. Anyone having a pointer to background info here?

Quote:
According to the following link
http://www.ciphersbyritter.com/ARTS/CRCMYST.HTM
a (specific) CRC-8 has a "99.29"% probability of catching errors...
The number you reference here is for a standard 8-bit checksum, not a CRC-8. A CRC-8 does better than this, it will detect 255/256=99,61% of all possible error bit patterns. Note that this is only the percentage of the number of error patterns recognized, depending on the type of errors in your system a 100% detection rate might apply, for example 1-bit errors are always detected.

Quote:
since the asm version is so fast, would it make sense to include 2 crc-8's in one package as opposed to a 16-bit crc? Doing it like this:
[msg header][address][ack][len][Data1][Data2][Data n][CRC1][Data n+1][Data x][CRC2]
I wouldn't do this, a CRC-16 is more safe than a CRC-8 and you are sending 16 bits of CRC anyway. I posted a very efficient CRC-16 function in the code library which is just as efficient as the CRC-8 above. http://www.ccsinfo.com/forum/viewtopic.php?t=24977
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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