standard crc-16 with 0x8005 polynomial in k64 mcu hardware CRC module

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

standard crc-16 with 0x8005 polynomial in k64 mcu hardware CRC module

Jump to solution
2,785 Views
wulinweng
Contributor II

Hi, I use a K64F120M and have probelms getting correct CRC-16 result using the built in hardware CRC generator.

the software calculation is below:

/* Table of CRC values for high byte */
const uchar auchCRCHi[] = {
0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U,
0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U,
0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U,
0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U,
0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U,
0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U,
0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U,
0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U,
0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U,
0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U,
0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U,
0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U,
0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U,
0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U,
0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U,
0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U,
0x00U, 0xC1U, 0x81U, 0x40U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x01U, 0xC0U, 0x80U, 0x41U, 0x00U, 0xC1U, 0x81U,
0x40U
} ;

/* Table of CRC values for low byte */
const uchar auchCRCLo[] = {
0x00U, 0xC0U, 0xC1U, 0x01U, 0xC3U, 0x03U, 0x02U, 0xC2U, 0xC6U, 0x06U, 0x07U, 0xC7U, 0x05U, 0xC5U, 0xC4U,
0x04U, 0xCCU, 0x0CU, 0x0DU, 0xCDU, 0x0FU, 0xCFU, 0xCEU, 0x0EU, 0x0AU, 0xCAU, 0xCBU, 0x0BU, 0xC9U, 0x09U,
0x08U, 0xC8U, 0xD8U, 0x18U, 0x19U, 0xD9U, 0x1BU, 0xDBU, 0xDAU, 0x1AU, 0x1EU, 0xDEU, 0xDFU, 0x1FU, 0xDDU,
0x1DU, 0x1CU, 0xDCU, 0x14U, 0xD4U, 0xD5U, 0x15U, 0xD7U, 0x17U, 0x16U, 0xD6U, 0xD2U, 0x12U, 0x13U, 0xD3U,
0x11U, 0xD1U, 0xD0U, 0x10U, 0xF0U, 0x30U, 0x31U, 0xF1U, 0x33U, 0xF3U, 0xF2U, 0x32U, 0x36U, 0xF6U, 0xF7U,
0x37U, 0xF5U, 0x35U, 0x34U, 0xF4U, 0x3CU, 0xFCU, 0xFDU, 0x3DU, 0xFFU, 0x3FU, 0x3EU, 0xFEU, 0xFAU, 0x3AU,
0x3BU, 0xFBU, 0x39U, 0xF9U, 0xF8U, 0x38U, 0x28U, 0xE8U, 0xE9U, 0x29U, 0xEBU, 0x2BU, 0x2AU, 0xEAU, 0xEEU,
0x2EU, 0x2FU, 0xEFU, 0x2DU, 0xEDU, 0xECU, 0x2CU, 0xE4U, 0x24U, 0x25U, 0xE5U, 0x27U, 0xE7U, 0xE6U, 0x26U,
0x22U, 0xE2U, 0xE3U, 0x23U, 0xE1U, 0x21U, 0x20U, 0xE0U, 0xA0U, 0x60U, 0x61U, 0xA1U, 0x63U, 0xA3U, 0xA2U,
0x62U, 0x66U, 0xA6U, 0xA7U, 0x67U, 0xA5U, 0x65U, 0x64U, 0xA4U, 0x6CU, 0xACU, 0xADU, 0x6DU, 0xAFU, 0x6FU,
0x6EU, 0xAEU, 0xAAU, 0x6AU, 0x6BU, 0xABU, 0x69U, 0xA9U, 0xA8U, 0x68U, 0x78U, 0xB8U, 0xB9U, 0x79U, 0xBBU,
0x7BU, 0x7AU, 0xBAU, 0xBEU, 0x7EU, 0x7FU, 0xBFU, 0x7DU, 0xBDU, 0xBCU, 0x7CU, 0xB4U, 0x74U, 0x75U, 0xB5U,
0x77U, 0xB7U, 0xB6U, 0x76U, 0x72U, 0xB2U, 0xB3U, 0x73U, 0xB1U, 0x71U, 0x70U, 0xB0U, 0x50U, 0x90U, 0x91U,
0x51U, 0x93U, 0x53U, 0x52U, 0x92U, 0x96U, 0x56U, 0x57U, 0x97U, 0x55U, 0x95U, 0x94U, 0x54U, 0x9CU, 0x5CU,
0x5DU, 0x9DU, 0x5FU, 0x9FU, 0x9EU, 0x5EU, 0x5AU, 0x9AU, 0x9BU, 0x5BU, 0x99U, 0x59U, 0x58U, 0x98U, 0x88U,
0x48U, 0x49U, 0x89U, 0x4BU, 0x8BU, 0x8AU, 0x4AU, 0x4EU, 0x8EU, 0x8FU, 0x4FU, 0x8DU, 0x4DU, 0x4CU, 0x8CU,
0x44U, 0x84U, 0x85U, 0x45U, 0x87U, 0x47U, 0x46U, 0x86U, 0x82U, 0x42U, 0x43U, 0x83U, 0x41U, 0x81U, 0x80U,
0x40U
} ;

uint CRC16(const uchar puchMsg[], uint32_t usDataLen)

{

uchar uchCRCHi = 0xFFU ; /* high byte of CRC initialized */

uchar uchCRCLo = 0xFFU ; /* low byte of f initialized */

        uint result;

uchar uIndex ; /* will index into CRC lookup table */

uint index=0U;

  while (usDataLen--) /* pass through message buffer */

{

  uIndex = uchCRCHi ^ puchMsg[index++] ; /* calculate the CRC */

  uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;

  uchCRCLo = auchCRCLo[uIndex] ;

}

        result = ((uint)uchCRCHi << 8 );

        result |= ((uint)uchCRCLo);

return (result);

}

but I can't get the right crc result to match the software in hardware crc module calculation, and the source code used hardware is below:

uint CRC16_H(const uchar puchMsg[], uint32_t usDataLen)

{

    uint result;

uchar uIndex ; /* will index into CRC lookup table */

uint index=0U;

CRC_CTRL &= ~CRC_CTRL_TCRC_MASK;

CRC_CTRL |= CRC_CTRL_TOT(3);

CRC_CTRL |= CRC_CTRL_TOTR(3);

CRC_CTRL |= CRC_CTRL_FXOR_MASK;

CRC_GPOLY = 0x8005U;

CRC_CTRL |= CRC_CTRL_WAS_MASK;

CRC_DATA = 0xFFFFU;

CRC_CTRL &= ~CRC_CTRL_WAS_MASK;

   while (usDataLen--) /* pass through message buffer */

{

  CRC_DATA = puchMsg[index++];

}

result = (uint)CRC_DATA;

return (result);

}

Can you help me to set the register for the crc-16 standard to match the software calculation?

BR,

Labels (1)
0 Kudos
1 Solution
1,344 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Please refer below code, which I had done the test with TWR-K64F120M board:

void crc_test(void)

{

  uint32_t data_out;

  int i;

  SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;

  // test CRC-16 feature with seed 0x0, data 0x4142, poly 0x8005, expect CRC result 0x61B0

  CRC_CTRL = CRC_CTRL_TOT(1) | CRC_CTRL_TOTR(2);

  CRC_GPOLY = 0x8005;

  CRC_CTRL |= CRC_CTRL_WAS_MASK;

  CRC_DATA = 0x0;

  CRC_CTRL &= ~CRC_CTRL_WAS_MASK;

  CRC_DATA = 0x4142;

    // wait for finish CRC calculation

    for(i=0;i<20;i++)

        ;

   // read result

   data_out = CRC_DATA;

    if(CRC_CTRL&0x20000000)

    {

        // byte transposition

        data_out = data_out>>16;

    }

    else

    {

        data_out &= 0x0000FFFF;

    }

    printf("expected value: 0x61B0, actual value: %x\n", data_out); 

}

You could verify the CRC-16 result from below link, and I also attached the CRC-16 calculation result for your reference.

http://www.lammertbies.nl/comm/info/crc-calculation.html

pastedImage_2.png

CRC-16 result.png


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

0 Kudos
4 Replies
1,344 Views
wulinweng
Contributor II

Can anybody help me to solve this?

Thanks

0 Kudos
1,344 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

I would recommend you to refer Kinetis 120MHz example, which includes CRC example:

Kinetis 120MHz bare metal sample code

So far, KSDK software library also provides K64 CRC module driver, you could find related CRC example at default folder:

C:\Freescale\KSDK_1.2.0\examples\frdmk64f\driver_examples\crc\iar

Wish it helps.


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
1,344 Views
wulinweng
Contributor II

Thank you fro your reply.

But I can't get the same value with the software calculation either.

Can you according to the software way tell me what the register of CRC_CTRL, CRC_GPOLY, CRC_DATA setting directly?

Thank you & Best Regards,

0 Kudos
1,345 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Please refer below code, which I had done the test with TWR-K64F120M board:

void crc_test(void)

{

  uint32_t data_out;

  int i;

  SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;

  // test CRC-16 feature with seed 0x0, data 0x4142, poly 0x8005, expect CRC result 0x61B0

  CRC_CTRL = CRC_CTRL_TOT(1) | CRC_CTRL_TOTR(2);

  CRC_GPOLY = 0x8005;

  CRC_CTRL |= CRC_CTRL_WAS_MASK;

  CRC_DATA = 0x0;

  CRC_CTRL &= ~CRC_CTRL_WAS_MASK;

  CRC_DATA = 0x4142;

    // wait for finish CRC calculation

    for(i=0;i<20;i++)

        ;

   // read result

   data_out = CRC_DATA;

    if(CRC_CTRL&0x20000000)

    {

        // byte transposition

        data_out = data_out>>16;

    }

    else

    {

        data_out &= 0x0000FFFF;

    }

    printf("expected value: 0x61B0, actual value: %x\n", data_out); 

}

You could verify the CRC-16 result from below link, and I also attached the CRC-16 calculation result for your reference.

http://www.lammertbies.nl/comm/info/crc-calculation.html

pastedImage_2.png

CRC-16 result.png


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos