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.

Trouble getting correct output from hardware CRC module (TM4C1294KCPDT)

Hello,

I'm trying to use hardware CRC module to accelerate checksum computation but unfortunately I'm not getting the same results as when I use software implementation of CRC module from TivaWare library. The CRC alghoritm is CRC16-IBM (polynomial 0x8005).

Example code:

	CRCConfigSet(CCM0_BASE, CRC_CFG_INIT_0 | CRC_CFG_SIZE_8BIT | CRC_CFG_TYPE_P8005);

        uint8_t test_data[4] = {0xFA, 0xFB, 0xFC, 0xFD};

        uint32_t hw_crc = CRCDataProcess(CCM0_BASE, test_data, 4, 0); //hw_crc == 0x0000CE75
        uint32_t sw_crc = Crc16(0, test_data, 4); //sw_crc == 0x0000A8C1

After call to CRCDataProcess registers looks like this:




I've also tried to omit calling CRCDataProcess and write data directly to registers to rule out any possible bugs, but result is identical:

       
uint8_t test_data[4] = {0xFA, 0xFB, 0xFC, 0xFD};
CRCConfigSet(CCM0_BASE, CRC_CFG_INIT_0 | CRC_CFG_SIZE_8BIT | CRC_CFG_TYPE_P8005);
		int i;
		for(i = 0; i < 4; i++)
		{
			HWREG(CCM0_BASE + 0x414) = test_data[i];
		}
		uint32_t hw_crc = HWREG(CCM0_BASE + 0x410);

Is there something wrong with my CRCConfigSet call?

  • Hello _BT_

    We got a similar post in the past (albeit for CRC32)

    e2e.ti.com/.../2017170

    Can you please check the trail of posts to see if the same applies to your case (in terms of the debug steps)
  • Well, I've tried to use:
    CRCConfigSet(CCM0_BASE, CRC_CFG_INIT_1 | CRC_CFG_SIZE_8BIT | CRC_CFG_TYPE_P8005);
    CRCConfigSet(CCM0_BASE, CRC_CFG_INIT_1 | CRC_CFG_SIZE_32BIT | CRC_CFG_TYPE_P8005);
    CRCConfigSet(CCM0_BASE, CRC_CFG_INIT_0 | CRC_CFG_SIZE_32BIT | CRC_CFG_TYPE_P8005);
    But with no luck.
    I'm not sure if I should try using reverse/inverse and endianess options since I'm using simple byte array, not ascii string like in the post you've linked.
  • Hello _BT_,

    Can you please attach you CCS project and the expected results on the test pattern, which website you used for the calculating the same, so that it would be much easier for me to check the same on a crypto connected launchpad.
  • crc_test.zip

    For obvious reasons I cannot post my company's IP online. However I've recreated the issue in attached project. Here's its main.c:

    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include "TivaWare/driverlib/sysctl.h"
    #include "TivaWare/driverlib/sw_crc.h"
    #include "TivaWare/driverlib/crc.h"
    #include "TivaWare/inc/hw_types.h"
    #include "TivaWare/inc/hw_memmap.h"
    
    #define TEST_FRAME_1_SIZE 14
    #define TEST_FRAME_2_SIZE 80
    
    int main(void)
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_CCM0);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_CCM0));
    
    	/*
    	 * Test frames, last two bytes are expected crc of the rest of the frame.
    	 * Checksums of these were calculated by my PC app, with our own
    	 * implementation of CRC16-IBM algorithm, which happens to be almost
    	 * exactly the same as TivaWare software implementation (same lookup table etc.).
    	 */
    
        uint8_t test_frame_1[TEST_FRAME_1_SIZE]  = {
        	0x0d, 0xf0, 0x0e, 0x00, 0xf2, 0xff, 0x00, 0x00, 0x07, 0xe0, 0x03, 0x00,
        	0x0E, 0xC5
        };
    
        uint8_t test_frame_2[TEST_FRAME_2_SIZE]  = {
        	0x0D ,0xF0 ,0x50 ,0x00 ,0xB0, 0xFF ,0x00 ,0x00, 0x07 ,0xE0 ,0x01 ,0x00,
        	0x01 ,0x00 ,0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00 ,0x00,
        	0x00 ,0x00 ,0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00 ,0x00,
        	0x00 ,0x00 ,0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00 ,0x00,
        	0x00 ,0x00 ,0x00 ,0x00 ,0x01, 0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00 ,0x00,
        	0x00 ,0x00 ,0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00, 0x00 ,0x00 ,0x00 ,0x00,
        	0x00 ,0x00 ,0x00 ,0x00 ,0x00, 0x00 ,0xF8 ,0x6F
        };
    
    
        /*
         * compute checksum using hw module. Use description form datasheet
         * (www.ti.com/lit/ds/symlink/tm4c1294kcpdt.pdf, p. 946).
         * First, write cfg register:
         */
        HWREG(CCM0_BASE + 0x400) = CRC_CFG_TYPE_P8005 | CRC_CFG_SIZE_8BIT |
        		CRC_CFG_INIT_SEED;
    
        /*
         * write seed reg to 0:
         */
        HWREG(CCM0_BASE + 0x410) = 0;
    	int i;
    	/*
    	 * Write data in register with input data:
    	 */
    	for(i = 0; i < TEST_FRAME_1_SIZE - 2; i++)
    	{
    		HWREG(CCM0_BASE + 0x414) = test_frame_1[i];
    	}
    	uint32_t hw_crc_1 = HWREG(CCM0_BASE + 0x410); /* I've got 0xB7FE here */
    
        /*
         * repeat above steps to compute second checksum:
         */
        HWREG(CCM0_BASE + 0x410) = 0;
    	for(i = 0; i < TEST_FRAME_2_SIZE - 2; i++)
    	{
    		HWREG(CCM0_BASE + 0x414) = test_frame_2[i];
    	}
    	uint32_t hw_crc_2 = HWREG(CCM0_BASE + 0x410); /* hw_crc_2 = 0x41F1 */
    
        /*
         * use sofware checksum computation from TivWare library:
         */
        uint32_t sw_crc_1 = Crc16(0, test_frame_1, TEST_FRAME_1_SIZE - 2);
        uint32_t sw_crc_2 = Crc16(0, test_frame_2, TEST_FRAME_2_SIZE - 2);
    
        /*
         * expected checksum is calculated with exactly the same algorithm
         * as used in TivaWare library, so it should be the same.
         */
        uint16_t expected_crc_1 = test_frame_1[TEST_FRAME_1_SIZE - 2];
        expected_crc_1 |= test_frame_1[TEST_FRAME_1_SIZE - 1] << 8;
        uint16_t expected_crc_2 = test_frame_2[TEST_FRAME_2_SIZE - 2];
        expected_crc_2 |= test_frame_2[TEST_FRAME_2_SIZE - 1] << 8;
    
    
        /*
         * put breakpoint below to see if calucated checksums match:
         */
    
    	return 0;
    }

  • Have you had time to look into this?
  • Hello _BT_,

    Yes. The hardware computation matches the online calculator.

    www.ghsi.de/.../index.php

    I am debugging the SW calculator.
  • Hi, I am having the same problem. CRC_CFG_TYPE_P8005 output does not match the IBM CRC16. Was there a resolution to this?
  • Also, If I call from in a loop, each pass has different output.