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.

TMS570LC4357: CRC controller usage for calculation of Power on CRC , CRC for data transmission and reception with CAN.

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

Could some one brief on the ways to use CRC controller for 

1. Power on CRC calculation.(Flash and RAM region CRC calculation with Auto Mode)

2. CRC calculation for data transmission and reception with CAN.

I am using following tools,

Code Composer Studio Version: 8.1.0.00011 and Halcogen Version 4.06.00

  • Hello Sudhakar,

    The HALCoGen has a CRC example. It shows the CRC configuration step by step. The TRM has one chapter for CRC which contains several examples.

    The CRC module in the LC4357 device is implemented with a 64-bit polynomial as in f(x) = x^64 + x ^4 + x^3 + x + 1.

    The CRC on the RAM is not a good solution because the content of the RAM will be changing dynamically. So you don't really know the golden signature to compare with.

    CRC on flash is a good solution if you want to do it periodically. I will recommend PBIST on RAM on startup. Bear in mind that both flash and RAM are protected with ECC for every access during run time.
  • Hi QJ Wang,

    Thank you for the response.

    I have checked the examples given in section "18.3.2 Example Auto Mode Without Using Time Based Triggering".

    If I need to calculate CRC for Flash, how to determine the "Pre-determined CRC" for the Flash size of 4MB in Auto Mode.

    Do I need to use the following code for the calculation of "Pre-determined CRC" ?

    for i in 63 to 0 loop
       NEXT_CRC_VAL(0) := CRC_VAL(63) xor DATA(i);
          for j in 1 to 63 loop
             case j is
                when 1|3|4 =>
                   NEXT_CRC_VAL(j) :=
                      CRC_VAL(j - 1) xor CRC_VAL(63) xor DATA(i);
                when others =>
                   NEXT_CRC_VAL(j) := CRC_VAL(j - 1);
             end case;
          end loop;
       CRC_VAL := NEXT_CRC_VAL;
    end loop

    Only one CRC value is sufficient for the calculation or for every sector CRC value need to be calculated?  

    Please confirm.

  • You may find information on this post useful: e2e.ti.com/.../2805284
  • Thank you for the update.

    I have referred the thread "e2e.ti.com/.../2805284 and updated the code for automode using halcogen and attached the complete code.


    The updated code is similar to "18.3.1 Example: Auto Mode Using Time Based Event Triggering"" of TRM, except I have used SW trigger and instead of large memeory area I have used CRC calculation for the "crc_test_value = 0x8DF8A32C74B91F3E".

    In the code,  CH0 and CH1 are used to set up DMA.

    Following is the code,

    /* Include Files */

    #include "HL_sys_common.h"

    /* USER CODE BEGIN (1) */
    #include "HL_crc.h"
    #include "HL_sys_dma.h"

    /* USER CODE END */

    /** @fn void main(void)
    * @brief Application main function
    * @note This function is empty by default.
    *
    * This function is called after startup.
    * The user can use this function to implement the application.
    */

    /* USER CODE BEGIN (2) */
    #define FRAME_COUNT 0x1
    #define ELEMENT_COUNT 0x2

    g_dmaCTRL g_dmaCTRLPKT0, g_dmaCTRLPKT1; // dma control packet configuration stack

    int main(void)
    {
    /* USER CODE BEGIN (3) */

    uint64 result_crc = 0U;
    _enable_IRQ();
    uint64 crc_test_value = 0x8DF8A32C74B91F3E;
    crcInit();
    result_crc = crc_update_word(0U, crc_test_value);


    crcREG1->PCOUNT_REG1= FRAME_COUNT * ELEMENT_COUNT;
    crcREG1->SCOUNT_REG1 = 1;

    crcEnableNotification(crcREG1,1);

    g_dmaCTRLPKT0.SADD = (uint32_t)(&(result_crc));
    g_dmaCTRLPKT0.DADD = (uint32_t)(&(crcREG1->REGL1));
    g_dmaCTRLPKT0.CHCTRL = 0;
    g_dmaCTRLPKT0.FRCNT = FRAME_COUNT;
    g_dmaCTRLPKT0.ELCNT = ELEMENT_COUNT;

    g_dmaCTRLPKT0.ELDOFFSET = 0;
    g_dmaCTRLPKT0.ELSOFFSET = 0;
    g_dmaCTRLPKT0.FRDOFFSET = 0;
    g_dmaCTRLPKT0.FRSOFFSET = 0;
    g_dmaCTRLPKT0.PORTASGN = PORTA_READ_PORTB_WRITE;
    g_dmaCTRLPKT0.RDSIZE = ACCESS_64_BIT;
    g_dmaCTRLPKT0.WRSIZE = ACCESS_64_BIT;
    g_dmaCTRLPKT0.TTYPE = BLOCK_TRANSFER;
    g_dmaCTRLPKT0.ADDMODERD = ADDR_INC1;
    g_dmaCTRLPKT0.ADDMODEWR = ADDR_FIXED;
    g_dmaCTRLPKT0.AUTOINIT = AUTOINIT_ON;

    // setting dma control packets for receive
    dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT0);
    dmaSetChEnable(DMA_CH0 ,DMA_SW);

    g_dmaCTRLPKT1.SADD = (uint32_t)(&(crc_test_value));
    g_dmaCTRLPKT1.DADD = (uint32_t)(&(crcREG1->PSA_SIGREGL1));
    g_dmaCTRLPKT1.CHCTRL = 0;
    g_dmaCTRLPKT1.FRCNT = FRAME_COUNT;
    g_dmaCTRLPKT1.ELCNT = ELEMENT_COUNT;

    g_dmaCTRLPKT1.ELDOFFSET = 0;
    g_dmaCTRLPKT1.ELSOFFSET = 0;
    g_dmaCTRLPKT1.FRDOFFSET = 0;
    g_dmaCTRLPKT1.FRSOFFSET = 0;
    g_dmaCTRLPKT1.PORTASGN = PORTA_READ_PORTB_WRITE;
    g_dmaCTRLPKT1.RDSIZE = ACCESS_64_BIT;
    g_dmaCTRLPKT1.WRSIZE = ACCESS_64_BIT;
    g_dmaCTRLPKT1.TTYPE = BLOCK_TRANSFER;
    g_dmaCTRLPKT1.ADDMODERD = ADDR_FIXED;
    g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED;
    g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_ON;

    // setting dma control packets for receive
    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT1);
    dmaSetChEnable(DMA_CH1, DMA_SW);

    dmaEnable();

    while(1);
    /* USER CODE END */

    return 0;
    }

    /* USER CODE BEGIN (4) */

    /* USER CODE END */

    --------------------------------------------------------------------------------------------------------

    I have used following code to calculate the pre-determined CRC value,

    uint64 crc_update_word(uint64 crc, uint64 data)
    {
    int i, j;
    uint64 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 & (uint64)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 & ~((uint64)1 << j)) | ((((crc >> (j-1)) ^ (crc >> 63) ^ (data >> i)) & 1) << j);
    }
    else
    { // when others =>
    // NEXT_CRC_VAL(j) := CRC_VAL(j - 1);
    nextCrc = (nextCrc & ~((uint64)1 << j)) | (((crc >> (j-1)) & 1) << j);
    }
    // end case;
    } // end loop;
    crc = nextCrc;
    } // end loop

    return crc;
    }

    After execution of the project, the values present in the CRC Value register and PSA Sector Signature Register are as below,

    Crc1_Crc_ValL1 000000FB
    Crc1_Crc_ValH1 0000008C
    Crc1_PsaSecSigL1 0000CFB2
    Crc1_PsaSecSigH1 0000A088

    Issue: Pre-determined CRC value is not correctly transferred from source address to destination address(CRC value register).

    Also the similar case for PSA signature register. May be issue is with the DMA setting.

    Request you to check the code and provide response.

    I am using Code Composer Studio Version: 8.1.0.00011 and Halcogen Version 4.06.00

    4452.halcogen_example.zip

  • Could someone please look into the issue and respond?

  • Hello,

    1. CRC1 uses DMA channel 26
    dmaReqAssign(DMA_CH0, DMA_REQ26);
    2. PCOUNT should be 1 in your test case (64 bit data)
    3. Both Frame count and element count should be 1
  • hi QJ Wang,

    Thanks for the response. I modified the code as per the suggestion.

    I also modified  MPU Default Settings. In HalCoGen Region 3 default setting is, "MPU_PRIV_RW_USER_RW_NOEXEC". I made this region as MPU_PRIV_RW_USER_RW_EXEC. Then I could see the values in CRC value register.

    I observed the values of CRC value register and PSA Sector register.

    Content of Crc1_CrcValL1 = Content of Crc1_PsaSecSig_H1

    Content of Crc1_CrcValH1 = Content of Crc1_PsaSecSig_L1.

    Do I need to swap the content of CRC value register before comparison? 

  • Hello,

    What is the difference between the CRC value using HW CRC and the CRC value using crc_update_word()?


  • Hi QJ Wang,

    I have calculated the CRC values in auotmode for various "crc_test_value" values.

    The table present illustrates the details of the "crc_test_value" and its respective CRC value obtained from "crc_update_word()" and "HW CRC" for 4 "crc_test_value".

    CRC value obtained for 1st "crc_test_value =0x1234567812345678" from "crc_update_word"  is,

    CRC_Value_L1 = 84BB2EC9 and CRC_Value_H1 = 84BB2ED3.

    CRC value obtained for 1st "crc_test_value =0x1234567812345678" from "HWCRC module"  is,

    PsaSecSig_L1 =84BB2ED3 and PsaSecSig_H1 = 84BB2EC9.

    It is observed that, content of CRC_Value_L1 and CRC_Value_H1 is matching with content of PsaSecSig_H1 and PsaSecSig_L1  respectively.

    For the remaining "crc_test_value" of the following table, CRC_Value_L1 and CRC_Value_H1 is matching with content of PsaSecSig_H1 and PsaSecSig_L1, "except the last 8bits". 

    crc_test_value

    CRC value using "crc_update_word()"

    CRC value obtained using HW CRC module CRC Controller

     

    CRC_Value_L1

    CRC_Value_H1

    PsaSecSig_L1

    PsaSecSig_H1

    0x1234567812345678

    84BB2EC9

    84BB2ED3

    84BB2ED3

    84BB2EC9

     

     

     

     

     

    0xAB234538EF2487DE

    164BB500

    BA01CBF0

    BA01CB7C

    164BB5D0

     

     

     

     

     

    0x5600321C36891642

    2A02E706

    8742EC7D

    8742ECF1

    2A02E732

     

     

     

     

     

    0xEA0012B6EAFFFFFE

    CE018902

    C700000CA

    C7000001A

    CE0189D2

    Is there any update required to "crc_update_word()", to obtain the correct CRC value for last 8 bits, please check and confim.

    Thanks,

    Sudhakar

  • Hi QJ Wang,

    After referring to the link "e2e.ti.com/.../2805284, I have swapped the upper 32 bits and lower 32 bits before providing input to the function, then i could get the correct values for CRC value register and PSA Sector register. Also instead of "crc_update_word()" function, i have used, "crc_t crc_update(crc_t crc, const void *data, size_t data_len)".

    Thank you so much for your time and help.


    Thanks,
    Sudhakar