Hello,
I'm trying to find a SW algorithm which calculates the same CRC as the CRC unit in the TMS570LC4357 (see this thread: http://e2e.ti.com/support/microcontrollers/hercules/f/312/p/716945/2749159#2749159).
I tried an implementation of Richard Burke from this forum and also a table-based routine generated by pycrc, a tool that was recommended by Sunil Oak in the other thread.
What I see: The implementation of Richard Burk and the pycrc routine return exactly the same value, but they differ from the CRC generated by the HW CRC unit in the processor.
Here is my test code, including the pycrc parameters:
#define CRC_CTRL0 (*(volatile uint32 *)0xFE000000U) #define CRC_CTRL2 (*(volatile uint32 *)0xFE000010U) #define CRC_SIGREG (*(volatile uint64 *)0xFE000060U) /* Function from SafeTI Diagnostic Library (sl_misc.c) */ /*SAFETYMCUSW 61 D MR: 8.10,8.11 <APPROVED> Comment_1*/ uint64 SL_CRC_Calculate (uint64* startAddr, const uint32 count64) { volatile uint32 count = 0u; /* volatile in order to prevent from being optimised */ CRC_CTRL0 |= 0x00000001U; /* Reset the CRC Module */ CRC_CTRL0 &= 0xFFFFFFFEU; CRC_CTRL2 |= 0x00000003U; /* Configure to Full CPU Mode */ /*SAFETYMCUSW 134 S MR: 12.2 <APPROVED> Comment_5*/ /*SAFETYMCUSW 134 S MR: 12.2 <APPROVED> Comment_5*/ for (count=0u; count < count64; count++) { /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> Comment_2*/ /*SAFETYMCUSW 93 S MR: 6.1,6.2,10.1,10.2,10.3,10.4 <APPROVED> "LDRA Tool issue" */ CRC_SIGREG = (uint64)(*startAddr); /*SAFETYMCUSW 45 D MR:21.1 <APPROVED> Comment_2*/ /*SAFETYMCUSW 567 S MR:17.1,17.4 <APPROVED> "Pointer increment needed" */ startAddr++; } return(CRC_SIGREG); } /* Example for manual implementation by Richard Burke */ crc_t crc_update_word(crc_t crc, crc_t data) { int i, j; crc_t nextCrc = 0; // for i in 63 to 0 loop for(i = 63; i >= 0; i--) { // NEXT_CRC_VAL(0) := CRC_VAL(63) xor DATA(i); nextCrc = (nextCrc & (crc_t)0xfffffffffffffffe) | ((crc >> 63) ^ (data >> i)); // for j in 1 to 63 loop for(j = 1; j < 64; j++) { //case j is // when 1|3|4 => if(j == 1 || j == 3 || j == 4) { // NEXT_CRC_VAL(j) := CRC_VAL(j - 1) xor CRC_VAL(63) xor DATA(i); nextCrc = (nextCrc & ~((crc_t)1 << j)) | ((((crc >> (j-1)) ^ (crc >> 63) ^ (data >> i)) & 1) << j); } else { // when others => // NEXT_CRC_VAL(j) := CRC_VAL(j - 1); nextCrc = (nextCrc & ~((crc_t)1 << j)) | (((crc >> (j-1)) & 1) << j); } // end case; } // end loop; crc = nextCrc; } // end loop return crc; } void crc_test(void) { uint64 crc_test_value = 0x8DF8A32C74B91F3E; uint8 crc_test_array1[8] = {0x8D, 0xF8, 0xA3, 0x2C, 0x74, 0xB9, 0x1F, 0x3E}; uint64 result_crc_safe_ti_lib = 0U; uint64 result_crc_burke = 0U; uint64 result_crc_pycrc = 0U; result_crc_safe_ti_lib = SL_CRC_Calculate(&crc_test_value, 1U); crcInit(); /* Sets everything to zero and enables Full CPU Mode */ result_crc_burke = crc_update_word(0U, crc_test_value); /* * Generated on Wed Dec 12 12:46:55 2018 * by pycrc v0.9.1, https://pycrc.org * using the configuration: * - Width = 64 * - Poly = 0x000000000000001b * - XorIn = 0x0000000000000000 * - ReflectIn = False * - XorOut = 0x0000000000000000 * - ReflectOut = False * - Algorithm = table-driven * */ result_crc_pycrc = crc_init(); result_crc_pycrc = crc_update(result_crc_pycrc, (unsigned char *)&crc_test_value, 8); result_crc_pycrc = crc_finalize(result_crc_pycrc); while(1); }
Results:
result_crc_safe_ti_lib = 0x2646CEB873922B5F
result_crc_burke = 0x2646CED073922BFD
result_crc_pycrc = 0x2646CED073922BFD
The primitive polynomial is the same as mentioned in the reference manual of the processor and I disabled all additional reflections and XOR values.
What could be wrong?
Best regards,
Jens