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.
Hello,
I'm testing the CRC module and noticed, that the calculated values differ between the method using two 32 bit words and the 64 bit method implemented in the SafeTI Diagnostic Library. I compared the results with a SW-calculated method posted by Richard Burke in this thread ( https://e2e.ti.com/support/microcontrollers/hercules/f/312/p/104764/368714#368714 ), but the result also differs from the other methods.
Before every test using the CRC module, I reset the module, which sets the start value to 0, and sets the CRC unit to "Full CPU Mode".
Here is my Code:
#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 */ typedef uint64 crc_t; 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; uint64 result_crc_manual = 0U; uint64 result_crc_safe_ti_lib = 0U; uint64 result_crc_test1 = 0U; uint64 result_crc_test2 = 0U; crcInit(); /* Sets everything to zero and enables Full CPU Mode */ result_crc_manual = crc_update_word(0U, crc_test_value); result_crc_safe_ti_lib = SL_CRC_Calculate(&crc_test_value, 1U); /* test1: words not swapped */ crcInit(); crcREG1->PSA_SIGREGH1 = (uint32)(crc_test_value >> 32); crcREG1->PSA_SIGREGL1 = (uint32)crc_test_value; result_crc_test1 = crcGetPSASig(crcREG1, 0); /* test2: words swapped */ crcInit(); crcREG1->PSA_SIGREGH1 = (uint32)crc_test_value; crcREG1->PSA_SIGREGL1 = (uint32)(crc_test_value >> 32); result_crc_test2 = crcGetPSASig(crcREG1, 0); while(1); }
Here are the results:
result_crc_manual = 0x2646CED073922BFD
result_crc_safe_ti_lib = 0x2646CEB873922B5F
result_crc_test1 = 0x739225063C91C898
result_crc_test2 = 0x2646CBAC3105924B
I expected, that result_crc_manual, result_crc_safe_ti_lib and result_crc_test1 or ...2 should be the same, so what could be wrong with my test?
Thanks and regards,
Jens
Hello,
does anyone have an Idea why my SW-calculated CRC differs from the HW-calculated CRC?
Thanks and regards,
Jens