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_calculate Help...

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



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

CRC_calculate Help...
PostPosted: Sat Sep 25, 2010 5:09 pm     Reply with quote

Hi Developers..Smile
I've problem with calculation of specific CRC. I'll put simple test program for calculating CRC with example packet (data).

Code:
   ////////////////////////////////////////////////////////////////////////////////////////////
   #include <16F628A.h>                                                                      //
   #device *=16                                                                            //
   #fuses HS, NOWDT,PROTECT,BROWNOUT,PUT,NOLVP,MCLR ///////////////////////////////////////////
   #use delay(clock=10 000 000)                                                              //
   #use rs232(baud=9600,rcv=PIN_B1,xmit=PIN_B2,errors,enable=PIN_B3,STREAM=rs_485)           //
               //
   ////////////////////////////////////////////////////////////////////////////////////////////
 
 char   buffer_485_tx []={0xF2,0x94,0x02,0x00,0x37,0x38,0x30,0x30,0x30,0x33,0x32,0x30,0x36,0x31};
   
 char  pc_crc_tx ()
   {
     
      unsigned int16 hlp;
      int1  cary;
      int byte_counter;
      char CHEKSUM=0x00;
     
   printf ("START CRC CALC\n\r");

   for (byte_counter=0;byte_counter<=13;byte_counter++)
   {
       printf ("For byte No:******************************* %d \n\r",byte_counter);
       printf ("INPUT_BYTE %X\n\r",buffer_485_tx[byte_counter]);
       printf ("CHEKSUM: %X\n\r",CHEKSUM);
       printf ("HLP: %4X\n\r",hlp);
//////////////////////////////////////////////////////////////////
        hlp = buffer_485_tx[byte_counter] + CHEKSUM;
       printf ("HLP_0: %4X\n\r",hlp);
      if (hlp > 0xFF)
      {
         cary = 1;
      }else cary=0;
      printf ("Cary___________1: %d\n\r",cary);
      hlp=hlp & 0xFF;
      printf ("HLP_1: %4X\n\r",hlp);
      hlp=hlp+hlp;
       printf ("HLP_2: %4X\n\r",hlp);
      if (cary)
      {
         hlp++;
      }
      printf ("HLP_3: %4X\n\r",hlp);
      if(hlp>0xFF)
      {
         cary=1;
      }else cary=0;
     printf ("Cary___________2: %d\n\r",cary);
      hlp=hlp & 0xFF;
      printf ("HLP_4: %4X\n\r",hlp);
      if (!cary)
      {
         hlp=hlp ^ 0xDD;
      }
      printf ("HLP_5: %4X\n\r",hlp);
      if (hlp >=0xE0)
      {
         hlp=hlp-0xE0;
      }
      printf ("HLP_6: %4X\n\r",hlp);
      CHEKSUM = hlp;
     // fputc (CHEKSUM,rs_485);
   }
         printf ("CRC_byte_LAST: %X\n\r",CHEKSUM);
     return CHEKSUM;
   
   }
   
   
   void main (){
   
     
      while (TRUE)
      {
         delay_ms(1000);
         pc_crc_tx ();
         delay_ms(1000);
      }
   }
 


The Calculated CRC is 0x18, but it's Wrong. Correct CRC is 0x12.
Also I make test program with Visual C++ and Source work with little change of data type.
Any idea...??
Thanks before:)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Sep 25, 2010 9:54 pm     Reply with quote

Quote:
Also I make test program with Visual C++.

Did you get the algorithm from the internet ? If so, post a link to a
working version of the code that is written in C (not C++).
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 12:17 am     Reply with quote

PCM programmer wrote:
Quote:
Also I make test program with Visual C++.

Did you get the algorithm from the internet ? If so, post a link to a
working version of the code that is written in C (not C++).

Hi PCM:) I got the algorithm from Delphi working code. Also I've assembler code for 8086 CPU...
Code:
         
  ADDCHECK:  PUSH    AX             
                         ADD     AL,CHECKSUM
                         RCL     AL,1
                         JC      ADCK3
                           XOR     AL,11011101b
            ADCK3:       MOV     CHECKSUM,AL
                         SUB     AL,224 
                         JC      ADCK4
                           MOV     CHECKSUM,AL
            ADCK4:     POP     AX
                       RET

My Compiler version is v.4.104
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Sep 26, 2010 5:24 pm     Reply with quote

For me, it's far easier to translate the Intel x86 ASM code into PIC ASM
than to try to convert it to C, so that's what I did below. I also cleaned
up your function interface. I created a function called get_checksum()
with accepts a pointer to an array of bytes and also the size of the array,
and then it calculates the checksum on that array and returns the result.
Now, unlike your code, it's a self-contained function. You give it
parameters and it gives you a result.

Running it in MPLAB simulator with compiler vs. 4.112 gives 0x12, which
you said is the expected result, so it's probably working.
Quote:

Checksum = 12

Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

char buffer_485_tx[]={0xF2,0x94,0x02,0x00,0x37,0x38,0x30,0x30,0x30,0x33,0x32,0x30,0x36,0x31};

int8 get_checksum(int8 *buffer, int8 bufsize)
{
int8 i;
int8 AL;
int8 checksum;

if(bufsize == 0)  // Safety check.  Is the count = 0 ?
   return(0);     // Just return if so

checksum = 0; 

for(i = 0; i < bufsize; i++)
   {
    AL = buffer[i];

    #asm
    ;    ADD   AL,CHECKSUM  // Add checksum to AL, update Cy
         movf  checksum, W
         addwf AL,F
   
    ;    RCL   AL,1         // Rotate AL left, thru Cy
         rlcf  AL,F
   
    ;    JC    ADCK3        // Jump on Cy to ADCK3
         bc    ADCK3
   
    ;    XOR   AL,11011101b // XOR AL with 0xDD
         movlw 0xDD
         xorwf AL,F
    ADCK3:
    ;    MOV   CHECKSUM,AL  // Put AL in Checksum
         movff AL,checksum
   
    ;    MOV   CHECKSUM,AL  // Put AL in Checksum
    ;    SUB   AL,224 
         movlw 224
         subwf AL,F
   
    ;    JC    ADCK4
         bnc   ADCK4    // Cy is opposite with subwf so use bnc
   
    ;    MOV   CHECKSUM,AL   // Put AL in Checksum
         movff AL, checksum
    ADCK4:
    #endasm
   }

return(checksum);
}


/*
// Original x86 source code
 ADDCHECK:
            PUSH    AX             
            ADD     AL,CHECKSUM  // Add Checksum to AL, update Cy

            RCL     AL,1         // Rotate AL left, thru Cy
            JC      ADCK3        // Jump on Cy to ADCK3
            XOR     AL,11011101b // XOR AL with 0xDD
 ADCK3:   
            MOV     CHECKSUM,AL  // Put AL in Checksum
            SUB     AL,224       
            JC      ADCK4
            MOV     CHECKSUM,AL
 ADCK4:   
            POP     AX
            RET
*/


//======================================
void main()
{
int8 result;

result = get_checksum(buffer_485_tx, sizeof(buffer_485_tx));

printf("Checksum = %x\r", result);

while(1);
}
 
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 4:39 am     Reply with quote

PCM programmer wrote:
For me, it's far easier to translate the Intel x86 ASM code into PIC ASM
than to try to convert it to C, so that's what I did below. I also cleaned
up your function interface. I created a function called get_checksum()
with accepts a pointer to an array of bytes and also the size of the array,
and then it calculates the checksum on that array and returns the result.
Now, unlike your code, it's a self-contained function. You give it
parameters and it gives you a result.

Running it in MPLAB simulator with compiler vs. 4.112 gives 0x12, which
you said is the expected result, so it's probably working.
Quote:

Checksum = 12

Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

char buffer_485_tx[]={0xF2,0x94,0x02,0x00,0x37,0x38,0x30,0x30,0x30,0x33,0x32,0x30,0x36,0x31};

int8 get_checksum(int8 *buffer, int8 bufsize)
{
int8 i;
int8 AL;
int8 checksum;

if(bufsize == 0)  // Safety check.  Is the count = 0 ?
   return(0);     // Just return if so

checksum = 0; 

for(i = 0; i < bufsize; i++)
   {
    AL = buffer[i];

    #asm
    ;    ADD   AL,CHECKSUM  // Add checksum to AL, update Cy
         movf  checksum, W
         addwf AL,F
   
    ;    RCL   AL,1         // Rotate AL left, thru Cy
         rlcf  AL,F
   
    ;    JC    ADCK3        // Jump on Cy to ADCK3
         bc    ADCK3
   
    ;    XOR   AL,11011101b // XOR AL with 0xDD
         movlw 0xDD
         xorwf AL,F
    ADCK3:
    ;    MOV   CHECKSUM,AL  // Put AL in Checksum
         movff AL,checksum
   
    ;    MOV   CHECKSUM,AL  // Put AL in Checksum
    ;    SUB   AL,224 
         movlw 224
         subwf AL,F
   
    ;    JC    ADCK4
         bnc   ADCK4    // Cy is opposite with subwf so use bnc
   
    ;    MOV   CHECKSUM,AL   // Put AL in Checksum
         movff AL, checksum
    ADCK4:
    #endasm
   }

return(checksum);
}


/*
// Original x86 source code
 ADDCHECK:
            PUSH    AX             
            ADD     AL,CHECKSUM  // Add Checksum to AL, update Cy

            RCL     AL,1         // Rotate AL left, thru Cy
            JC      ADCK3        // Jump on Cy to ADCK3
            XOR     AL,11011101b // XOR AL with 0xDD
 ADCK3:   
            MOV     CHECKSUM,AL  // Put AL in Checksum
            SUB     AL,224       
            JC      ADCK4
            MOV     CHECKSUM,AL
 ADCK4:   
            POP     AX
            RET
*/


//======================================
void main()
{
int8 result;

result = get_checksum(buffer_485_tx, sizeof(buffer_485_tx));

printf("Checksum = %x\r", result);

while(1);
}
 
Thanks again .Smile PCM , but it dosn't work with PCM devices (14bit Parts), and return error from compilations "rlcf AL,F--->Expecting an opcode mnemonic"
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 4:53 am     Reply with quote

Just change RLCF to RLF.
On the PIC16, the only rotation does it through the carry, so there is just one instruction (fortunately the one we want!). On the PIC18's, other versions were added, so the instruction became 'RLCF' to say 'through the carry'.

Best Wishes
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 5:18 am     Reply with quote

Ttelmah wrote:
Just change RLCF to RLF.
On the PIC16, the only rotation does it through the carry, so there is just one instruction (fortunately the one we want!). On the PIC18's, other versions were added, so the instruction became 'RLCF' to say 'through the carry'.

Best Wishes

Hi Ttelmah Smile
I saw this , but have other ASM different instruction set ..
I have err on line : "bc ADCK3" What is "bc"??
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 7:05 am     Reply with quote

Branch if carry. Jumps to ADCK3, if the carry bit is set.

On the PIC16, this has to be done as:

#byte STATUS=3

Then in the assembler:
BTFSC STATUS,0
GOTO ADCK3

So you test the 'carry' bit in the status register, and if it is 'set' (carry), then execute the next instruction, which is the jump to ADCK3, otherwise skip this.

Best Wishes
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 7:26 am     Reply with quote

Ttelmah wrote:
Branch if carry. Jumps to ADCK3, if the carry bit is set.

On the PIC16, this has to be done as:

#byte STATUS=3

Then in the assembler:
BTFSC STATUS,0
GOTO ADCK3

So you test the 'carry' bit in the status register, and if it is 'set' (carry), then execute the next instruction, which is the jump to ADCK3, otherwise skip this.

Best Wishes


Hi Ttelmah Smile I made up this for BC --> BTFSC 3,0
goto ADCK3
and for bnc --> BTFSS 3,0
goto ADCK4
but still have a errors and diferent from MOVFF instruction

Question
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Mon Sep 27, 2010 9:09 am     Reply with quote

To 'put you out of your misery', I have done what PCM didn't want to, and changed the routine into C.
Code:

int8 get_checksum(int8 *buffer, int8 bufsize) {
   int8 i;
   int16 AL;
   int8 checksum,temp;
   int1 carry;

   if(bufsize == 0)  // Safety check.  Is the count = 0 ?
      return(0);     // Just return if so

   checksum = 0;

   for(i = 0; i < bufsize; i++) {
    AL = buffer[i];
    AL+=checksum;
    if (AL & 0x100)
         //Here have carry, so rotate one into the byte
         carry=shift_left(&AL,1,1);
    else
         //Else zero
         carry=shift_left(&AL,1,0);
    //Carry is now the bit that came out the bottom   
    if (carry==0)
       AL^=0xDD;
    temp=make8(AL,0); //Get LSB
    if (temp<224)
       checksum=temp;
    else
       checksum=temp-224;
   }
   return checksum;
}

I think this is 'right', and should work identically with PIC16 or PIC18 chips.

Best Wishes
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Tue Sep 28, 2010 9:04 am     Reply with quote

Hi Ttelmah ! Thanks for your help. Your 'C' CRC calc. routine work. I've never done programing in assembler, but with little reading data sheet - PIC instruction set summary and your help this also work:
Code:
 
int8 get_checksum(int8 *buffer, int8 bufsize)
{
int8 i;
int8 AL;
int8 checksum;
//#byte STATUS=3

if(bufsize == 0)  // Safety check.  Is the count = 0 ?
   return(0);     // Just return if so

checksum = 0;

for(i = 0; i < bufsize; i++)
   {
    AL = buffer[i];

    #asm
         movf  checksum, W
         addwf AL,F
   
         rlf  AL,F
   
         BTFSC 3,0
         goto ADCK3
   
         movlw 0xDD
         xorwf AL,F
    ADCK3:
         movf AL ,W
         movwf checksum
   
         movlw 224
         subwf AL,F //demo
   
         BTFSS 3,0
         goto ADCK4
         
         movf AL,W
         movwf checksum     
    ADCK4:
   
    #endasm
   }

return(checksum);
}
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