This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430F5325+CRC module+ error bytes not matching with using CRC16 algorithm

Other Parts Discussed in Thread: MSP430F5325

I am using MSP430F5325  in my hardware for MODBUS communication. My hardware is MOSBUS RTU slave. For MODBUS communication , I need to use CRC16 algorithm for checking errors in transmission/reception.

Following is the algorithm in C:

void main()
{
unsigned char data[NUMDATA+2];
// Message buffer
unsigned char Crc_HByte,LByte;
//
unsigned int Crc;
....
Crc=0xFFFF;
for (i=0; i<NUMDATA; i++) {
Crc = CRC16 (Crc, data[i] );
}
Crc_LByte = (Crc & 0x00FF);
// Calculate low-order byte
Crc_HByte = (Crc & 0xFF00) / 256;
// Calculate high-order byte
}
// CRC16 calculation
// ----------------
unsigned int
CRC16
(unsigned int crc, unsigned int data)
{
const unsigned int Poly16=0xA001;
unsigned int LSB, i;
crc = ((crc^data) | 0xFF00) & (crc | 0x00FF);
for (i=0; i<8; i++) {
LSB=(crc & 0x0001);
crc=crc/2;
if (LSB)
crc=crc^Poly16;
}
return(crc);
}

This is proven code for crc16 and it works absolutely fine in C on PC.Even it worked well with another micon hardware as a slave.

In order to implement this , I am using  CRC module of MSP430F5325. However, my crc  output from CRC module does not match with the above  code writen in C. The Master RTU issues CRC error due this mismatch.

Below is my code in CCS Ver 5.3

//////////////////code////////////////////////

unsigned char rx_frame[8];  //array for storing the query received from Master RTU

after detecting end of frame, i  store the received CRC from rx_frame buffer to temp variables  and I calculate crc from first 6  recieved bytes and compare them with the received one.

The received Crc and calculated Crc should match  for valid transmission and reception.

////////////code is as below://///////

           received_crc_low=rx_frame[6];
           received_crc_high=rx_frame[7];

           unsigned cal_received_crcL,calc_received_crcH;
         

//////////////calculate crc of received frame

A) without reversing bits:



          CRCINIRES=0xFFFF;  // initialize
            int zx;
                      for (zx=0;zx<6;zx++)
                      {
                         CRCDI_L=rx_frame[zx]; //8 byte
                       

                      }

                      cal_received_crcL=CRCINIRES_L;   //result lowbyte
                      calc_received_crcH=CRCINIRES_H; //result Highbyte

          //  compare "calculated Crclowbyte" with " received crc_lowbyte"  and "calculated CrcHighbyte" with " received crc_Highbyte"

              CRcs are not matching

    ///////////////////////////////////////////

B) with reversing bits:



          CRCINIRES=0xFFFF;  // initialize
            int zx;
                      for (zx=0;zx<6;zx++)
                      {
                   
                         CRCDIRB_L=rx_frame[zx];

                      }

                      cal_received_crcL=CRCRESR_L;
                      cal_received_crcH=CRCRESR_H;

          //  compare "calculated Crclowbyte" with " received crc_lowbyte"  and "calculated CrcHighbyte" with " received crc_Highbyte"

              Crcs are not matching

Please evaluarte the code and help understand what is going wrong.

  • Different polynoms: Modbus uses something the IBM-CRC-16 x^16 + x^15 + x^2 + 1 while the MSP430 uses the CRC-CCITT x^16 + x^12 + x^5 + 1.

    Hardy

    PS: change the modbus spec to allow usage of TIs CRC generator (;-)) or use a table approach or search for implementations where the loop has been transformed into some shifts and XORs.  Dont know how this is called, but the output looks like (again the CRC-CCITT polynom, stolen from Contiki):

    /* CITT CRC16 polynomial ^16 + ^12 + ^5 + 1 */
    /*---------------------------------------------------------------------------*/
    uint16_t crc16_add( uint8_t b, register uint16_t acc)
    {
      acc ^= b;
      acc  = (acc >> 8) | (acc << 8);
      acc ^= (acc & 0xff00) << 4;
      acc ^= (acc >> 8) >> 4;
      acc ^= (acc & 0xff00) >> 5;
      return acc;
    }


  • CRC module of MSP430 uses the polynomial 0x8408 (CRC-16-CCITT) while you want to use the polynomial 0xA001 (CRC-16-IBM). Of course they are not the same.

**Attention** This is a public forum