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.

CCS/TMS570LS3137: CRC auto-mode

Part Number: TMS570LS3137

Tool/software: Code Composer Studio

I want to test crc auto-mode,but I didn't get the crc value, Here is my code:

/** @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 0x1
#define D_SIZE 8
g_dmaCTRL g_dmaCTRLPKT0, g_dmaCTRLPKT1;    // dma control packet configuration stack




int main(void)
{
/* USER CODE BEGIN (3) */
    uint64 u64Signature = 0U;
    uint64 result_crc = 0U;
    _enable_IRQ();

//    uint32_t CRC1_Ref[2] = {0x5F7EAE33, 0x6233774E};
    uint64 crc_test_value = 0x8DF8A32C74B91F3E;
//    uint16 tx_data[D_SIZE] = {0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888};

    crcInit();
    result_crc = crc_update_word(0U, crc_test_value);


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

    crcEnableNotification(crcREG,1);

    dmaEnable();

    g_dmaCTRLPKT0.SADD = (uint32_t)(&(result_crc));

    //g_dmaCTRLPKT0.SADD = (uint32_t)0x08000FE8; //address of variable result_crc which holds the pre-determined CRC value.
//    g_dmaCTRLPKT0.SADD = (uint32_t)(&CRC1_Ref[0]);
    g_dmaCTRLPKT0.DADD = (uint32_t)(&(crcREG->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     = FRAME_TRANSFER;
       g_dmaCTRLPKT0.ADDMODERD = ADDR_INC1;
       g_dmaCTRLPKT0.ADDMODEWR = ADDR_FIXED;
       g_dmaCTRLPKT0.AUTOINIT  = AUTOINIT_OFF;

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

     g_dmaCTRLPKT1.SADD = (uint32_t)(&(crc_test_value));

   //g_dmaCTRLPKT1.SADD = (uint32_t)0x08000FF0;//address of crc_test_value from where the memory area to be verified.
//    g_dmaCTRLPKT1.SADD = (uint32_t)tx_data; /* source address */
    g_dmaCTRLPKT1.DADD = (uint32_t)(&(crcREG->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     = FRAME_TRANSFER;
    g_dmaCTRLPKT1.ADDMODERD = ADDR_FIXED;
    g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED;
    g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_OFF;

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

    while( crcREG->BUSY & 1ul )
        {
            /* Wait until DMA finsihed and CRC indicates block compressed */
        }

        u64Signature = crcGetSectorSig(crcREG, CRC_CH1);

        /* Clear CH1_CCIT bit */
        crcREG->STATUS = CRC_CH1_CC;

        if(u64Signature != result_crc){
            printf("wrong!,result_crc is %llx,u64Signature is %llx",result_crc,u64Signature);
        }else{
            printf("right!");
        }
//        printf("%llx \n",u64Signature);
 //   while(1);
/* USER CODE END */

    return 0;
}

  • Hello,

    In CRC AUTO mode, the data transfer to both the PSA Signature Register and CRC Value Register are performed in the background of CPU. When a mismatch is detected, an interrupt is generated to CPU. You don't need to compare manually. 

    This line is not correct. PORTA_READ_PORTB_WRITE is for TMS570LC43x and RM57x devices. For LS31x device, 0x4 should be used.

     g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;

  • Hello QJ Wang,

    I modified the code,but the PSA sector signature register has no value,CRC_Value_L1 and CRC_Value_H1 is matching with content of PsaSig_H1 and PsaSig_L1, except the last 8bits,and the BUSY flag is still set,here is my code,or can you give me an example of auto mode?

    /* USER CODE BEGIN (2) */
    #define FRAME_COUNT 0x1
    #define ELEMENT_COUNT 0x1
    #define D_SIZE 8
    g_dmaCTRL g_dmaCTRLPKT0, g_dmaCTRLPKT1;    // dma control packet configuration stack
    
    
    
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
    //    uint64 u64Signature = 0U;
        uint64 result_crc = 0U;
        _enable_IRQ();
    
    //    uint32_t CRC1_Ref[2] = {0x5F7EAE33, 0x6233774E};
        uint64 crc_test_value = 0x8DF8A32C74B91F3E;
    //    uint16 tx_data[D_SIZE] = {0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888};
    
        crcInit();
        result_crc = crc_update_word(0U, crc_test_value);
        printf("%llx \n",result_crc);
    
        crcREG->PCOUNT_REG1= FRAME_COUNT * ELEMENT_COUNT;
        crcREG->SCOUNT_REG1 = 1;
    
        crcEnableNotification(crcREG,1);
    
        dmaEnable();
    
        g_dmaCTRLPKT0.SADD = (uint32_t)(&(result_crc));
    
        //g_dmaCTRLPKT0.SADD = (uint32_t)0x08000FE8; //address of variable result_crc which holds the pre-determined CRC value.
    //    g_dmaCTRLPKT0.SADD = (uint32_t)(&CRC1_Ref[0]);
        g_dmaCTRLPKT0.DADD = (uint32_t)(&(crcREG->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  = 4;
           g_dmaCTRLPKT0.RDSIZE    = ACCESS_64_BIT;
           g_dmaCTRLPKT0.WRSIZE    = ACCESS_64_BIT;
           g_dmaCTRLPKT0.TTYPE     = FRAME_TRANSFER;
           g_dmaCTRLPKT0.ADDMODERD = ADDR_FIXED;
           g_dmaCTRLPKT0.ADDMODEWR = ADDR_FIXED;
           g_dmaCTRLPKT0.AUTOINIT  = AUTOINIT_OFF;
    
           // setting dma control packets for receive
           dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT0);
    //       dmaReqAssign(DMA_CH0, DMA_REQ26);
           dmaSetChEnable(DMA_CH0 ,DMA_SW);
    
         g_dmaCTRLPKT1.SADD = (uint32_t)(&(crc_test_value));
    
       //g_dmaCTRLPKT1.SADD = (uint32_t)0x08000FF0;//address of crc_test_value from where the memory area to be verified.
    //    g_dmaCTRLPKT1.SADD = (uint32_t)tx_data; /* source address */
        g_dmaCTRLPKT1.DADD = (uint32_t)(&(crcREG->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  = 4;
        g_dmaCTRLPKT1.RDSIZE    = ACCESS_64_BIT;
        g_dmaCTRLPKT1.WRSIZE    = ACCESS_64_BIT;
        g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER;
        g_dmaCTRLPKT1.ADDMODERD = ADDR_FIXED;
        g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED;
        g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_OFF;
    
        // setting dma control packets for receive
        dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT1);
        dmaSetChEnable(DMA_CH1, DMA_SW);
    
     /**   while( crcREG->BUSY & 1ul )
            {
    
            }
    
            u64Signature = crcGetSectorSig(crcREG, CRC_CH1);
    
    
            crcREG->STATUS = CRC_CH1_CC;
    
            if(u64Signature != result_crc){
                printf("wrong!,result_crc is %llx,u64Signature is %llx",result_crc,u64Signature);
            }else{
                printf("right!");
            }
      */
    //        printf("%llx \n",u64Signature);
    //    while(1);
    /* USER CODE END */
    
        return 0;
    }


  • Is there anything wrong with this code?
    uint64 crc_update_word(uint64 crc64, 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 & 0xfffffffffffffffeULL) | ((crc64 >> 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 & ~(1ULL << j)) | ((((crc64 >> (j -
    1)) ^ (crc64 >> 63) ^ (data >> i)) & 1) << j);
    }
    else
    { // when others =>
    // NEXT_CRC_VAL(j) := CRC_VAL(j - 1);
    nextCrc = (nextCrc & ~(1ULL << j)) | (((crc64 >> (j - 1)) & 1) << j);
    }
    // end case;
    } // end loop;
    crc64 = nextCrc;
    } // end loop
    return crc64;
    }
    

  • Please check if the BUSY register is set.

  • Hello,

    I noticed that the new PCOUNT and SCOUNT won't take effect, please call     crcChannelReset(crcREG, 0x0); before that:

        crcChannelReset(crcREG, 0x0);

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

     

  • Hello QJ Wang,

    I modified the code,and the PSA sector signature register has value,but the lower 8 bits of the PsaSig_H1 and PsaSig_L1 value do not match the CRC_Value_L1 and CRC_Value_H1,here is the code:

    /* USER CODE BEGIN (2) */
    #define FRAME_COUNT 0x1
    #define ELEMENT_COUNT 0x1
    #define D_SIZE 8
    g_dmaCTRL g_dmaCTRLPKT0, g_dmaCTRLPKT1;    // dma control packet configuration stack
    
    
    
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
    //    uint64 u64Signature = 0U;
        uint64 result_crc = 0U;
    //    _enable_IRQ();
    
    //    uint32_t CRC1_Ref[2] = {0x5F7EAE33, 0x6233774E};
        uint64 crc_test_value = 0x8DF8A32C74B91F3E;
    //    uint16 tx_data[D_SIZE] = {0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888};
    //    uint64 *p = &crc_test_value;
        crcInit();
        dmaEnable();
        /* Enable all interrupts for Channel 0 */
                crcEnableNotification(crcREG,
                        CRC_CH1_CC |
                        CRC_CH1_FAIL |
                        CRC_CH1_OR |
                        CRC_CH1_UR |
                        CRC_CH1_TO);
    
    
    
        result_crc = crc_update_word(0U, crc_test_value);
    //    result_crc = calc_crc64(p,1);
        printf("%llx \n",result_crc);
    
    //    crcREG->PCOUNT_REG1= FRAME_COUNT * ELEMENT_COUNT;
    //    crcREG->SCOUNT_REG1 = 1;
    
    //    crcEnableNotification(crcREG,1);
    
        crcConfig_t     sCrcParams;
    
        sCrcParams.crc_channel   = CRC_CH1;
        sCrcParams.mode          = CRC_AUTO;
        sCrcParams.pcount        = 1;
        sCrcParams.scount        = 1u;
        sCrcParams.wdg_preload   = 0u;
        sCrcParams.block_preload = 0u;
    
        crcChannelReset(crcREG, CRC_CH1);
        crcSetConfig(crcREG, &sCrcParams);
    
        g_dmaCTRLPKT0.SADD = (uint32_t)(&(result_crc));
    
        //g_dmaCTRLPKT0.SADD = (uint32_t)0x08000FE8; //address of variable result_crc which holds the pre-determined CRC value.
    //    g_dmaCTRLPKT0.SADD = (uint32_t)(&CRC1_Ref[0]);
        g_dmaCTRLPKT0.DADD = (uint32_t)(&(crcREG->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  = 4;
           g_dmaCTRLPKT0.RDSIZE    = ACCESS_64_BIT;
           g_dmaCTRLPKT0.WRSIZE    = ACCESS_64_BIT;
           g_dmaCTRLPKT0.TTYPE     = FRAME_TRANSFER;
           g_dmaCTRLPKT0.ADDMODERD = ADDR_FIXED;
           g_dmaCTRLPKT0.ADDMODEWR = ADDR_FIXED;
           g_dmaCTRLPKT0.AUTOINIT  = AUTOINIT_OFF;
    
           // setting dma control packets for receive
           dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT0);
    //       dmaReqAssign(DMA_CH0, DMA_REQ26);
           dmaSetChEnable(DMA_CH0 ,DMA_SW);
    
         g_dmaCTRLPKT1.SADD = (uint32_t)(&(crc_test_value));
    
       //g_dmaCTRLPKT1.SADD = (uint32_t)0x08000FF0;//address of crc_test_value from where the memory area to be verified.
    //    g_dmaCTRLPKT1.SADD = (uint32_t)tx_data; /* source address */
        g_dmaCTRLPKT1.DADD = (uint32_t)(&(crcREG->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  = 4;
        g_dmaCTRLPKT1.RDSIZE    = ACCESS_64_BIT;
        g_dmaCTRLPKT1.WRSIZE    = ACCESS_64_BIT;
        g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER;
        g_dmaCTRLPKT1.ADDMODERD = ADDR_FIXED;
        g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED;
        g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_OFF;
    
        // setting dma control packets for receive
        dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT1);
        dmaSetChEnable(DMA_CH1, DMA_SW);
    
     /**   while( crcREG->BUSY & 1ul )
            {
    
            }
    
            u64Signature = crcGetSectorSig(crcREG, CRC_CH1);
    
    
            crcREG->STATUS = CRC_CH1_CC;
    
            if(u64Signature != result_crc){
                printf("wrong!,result_crc is %llx,u64Signature is %llx",result_crc,u64Signature);
            }else{
                printf("right!");
            }
      */
    //        printf("%llx \n",u64Signature);
    //    while(1);
    /* USER CODE END */
    
        return 0;
    }
    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;
    }

  • Hello,

    1. The CRC value (crc_result) from crc_update_word() should be swapped between upper 32-bit word and lower 32-bit word before transfer to CRC registers. 

         The crc_result = 0x2646CED073922BFD, sine TMS570 is a big endian device, the upper word is loaded to CRC Value Low Register (crcREG->REGL1).

         So we need to swap the upper and lower word first.

    2. Same for using PSA signature registers.  We need to swap the upper and lower 32-bit values in the input string before input to the CRC PSA signature registers. So in your case, pass the value 0x74B91F3E8DF8A32C as input.

    Attached is my test code.7041.sys_main.c