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: Hardware CRC using HalCoGen code

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN

I'm trying to use the hardware CRC in Semi-CPU Polling mode.  Following the flow chart in Figure 4 https://www.ti.com/lit/an/spna235/spna235.pdf

I set up the CRC module by calling:

#define DATA_LENGTH 2048
uint8 data[DATA_LENGTH];
g_dmaCTRL crcDmaCtrl = {reinterpret_cast<uint32_t>(&(data[0])),
        reinterpret_cast<uint32_t>(&(crcREG1->PSA_SIGREGL1)),
        0,
        1, // FRCNT
        DATA_LENGTH / 8,
        0,
        0,
        0,
        0,
        PORTA_READ_PORTA_WRITE,
        ACCESS_64_BIT,
        ACCESS_64_BIT,
        BLOCK_TRANSFER,
        ADDR_INC1,
        ADDR_FIXED,
        AUTOINIT_OFF};

crcConfig_t crcModuleConfig =
        {CRC_CH1,
        CRC_SEMI_CPU,
        crcDmaCtrl.ELCNT,
        crcDmaCtrl.FRCNT,
        0xffffffff,   // Not sure what to put here
        0xffffffff};  // Not sure what to put here
crcInit();
dmaEnable();
crcChannelReset(crcREG1, CRC_CH1);
crcSetConfig(crcREG1, &crcModuleConfig);
dmaSetCtrlPacket(DMA_CH8, crcDmaCtrl);
dmaSetChEnable(DMA_CH8, DMA_SW);
while(crcREG1->BUSY);
uint64 hwCRC = crcGetSectorSig(crcREG1, CRC_CH1);   // Always Zero 0
As noted above, the hwCRC is always Zero.  How can I troubleshoot this?
Thanks,
Matt
  • Hi Matt,

    We started working on your thread and will provide an update ASAP.

    --

    Thanks & regards,
    Jagadish.

  • Any updates?

    I tried running in FULL CPU MODE using crcSignGen and crcGetPSASig.  I was able to get a crc64 using those functions.

    However, I still cannot get SEMI CPU POLLING to work.  I found some TI example code, but it doesn't work either:

    crcInit();


    dmaEnable();

    /* Enable all interrupts for Channel 0 */
    crcEnableNotification(crcREG1, CRC_CH1_CC | CRC_CH1_FAIL | CRC_CH1_OR | CRC_CH1_UR | CRC_CH1_TO);

    crcConfig_t sCrcParams;
    g_dmaCTRL g_dmaCTRLPKT;

    g_dmaCTRLPKT.SADD = (uint32_t) & (myBuffer); /* initial source address */
    g_dmaCTRLPKT.DADD = (uint32_t)(&(crcREG1->PSA_SIGREGL1)); /* initial destination address */
    g_dmaCTRLPKT.CHCTRL = 0ul; /* channel control */
    g_dmaCTRLPKT.RDSIZE = ACCESS_64_BIT; /* read size */
    g_dmaCTRLPKT.WRSIZE = ACCESS_64_BIT; /* write size */
    g_dmaCTRLPKT.FRCNT = 1; /* frame count */
    g_dmaCTRLPKT.ELCNT = (BUFFER_LENGTH + 7ul) / 8ul; /* element count */
    g_dmaCTRLPKT.ELSOFFSET = 0ul << g_dmaCTRLPKT.RDSIZE; /* element source offset */
    g_dmaCTRLPKT.FRSOFFSET = 0ul << g_dmaCTRLPKT.RDSIZE; /* frame source offset */
    g_dmaCTRLPKT.ELDOFFSET = 0ul << g_dmaCTRLPKT.WRSIZE; /* element destination offset */
    g_dmaCTRLPKT.FRDOFFSET = 0ul << g_dmaCTRLPKT.WRSIZE; /* frame destination offset */
    g_dmaCTRLPKT.PORTASGN = 4ul; /* only Port B */
    g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER; /* transfer type */
    g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; /* address mode read */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */
    g_dmaCTRLPKT.AUTOINIT = AUTOINIT_OFF; /* autoinit off */

    sCrcParams.crc_channel = CRC_CH1;
    sCrcParams.mode = CRC_SEMI_CPU;
    sCrcParams.pcount = g_dmaCTRLPKT.ELCNT;
    sCrcParams.scount = 1u;
    sCrcParams.wdg_preload = 0u;
    sCrcParams.block_preload = 0u;

    crcChannelReset(crcREG1, CRC_CH1);
    crcSetConfig(crcREG1, &sCrcParams);

    dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT);
    dmaSetChEnable(DMA_CH0, DMA_SW);

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

    volatile uint64_t u64Signature = 0ull;
    u64Signature = crcGetSectorSig(crcREG1, CRC_CH1);

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

    After the above code, u64Signature is always 0

  • I have a sort-of working implementation.  The attached file shows an implementation of Semi CPU, Full CPU, and Software only CRC64.  Then I run main() code like:

    #define DATA_LEN 1280
    uint8_t data[DATA_LEN];

    for (uint32_t i = 0; i < AVIODD_DATA_LENGTH; i++)
    {
    data[i] = 0xaa;
    }
    while(1)
    {
      uint64_t semi_cpu_crc64 = RunCRC64SemiCPU(reinterpret_cast<uint32_t>(data), DATA_LEN / 8);
      uint64_t full_cpu_crc64 = RunCRC64FullCPU(reinterpret_cast<uint64_t*>(data), DATA_LEN / 8);
      uint64_t swCRC = calc_crc64(reinterpret_cast<uint64_t*>(data), DATA_LEN / 8);
    }
    Full CPU and Software always product the correct value:  13505979422727838331
    Semi CPU produces the following values each iteration of the loop:
    1st iteration:  0
    2nd iteration: 2861055741797597537
    3rd iteration: 15659176631280312865
    4th iteration and all subsequent iterations yield the correct value:  13505979422727838331

    How do I get the correct value the first time, every time using Semi CPU?

    CrcUtils.cpp

  • Hi Matt,

    Give me some time to reproduce the issue at my end.

    --

    Thanks & regards,
    Jagadish.

  • How do I get the correct value the first time, every time using Semi CPU?

    Does your HALCoGen configuration enable the processor cache, and if so what is the MPU configuration for the SRAM?

    Looking at the TMS570LC43x 16/32 RISC Flash Microcontroller Technical Reference Manual (Rev. A):

    • Semi CPU mode uses DMA
    • DMA PortA is funneled into ACP-S slave port.

    The Accelerated Coherency Port (ACP) has support for hardware cache coherency but Accelerator Coherency Port interface from the ARM Cortex-R5 reference manual does say:

    The Cortex-R5 ACP memory coherency scheme only provides coherency between an external master connected to the ACP slave port and a CPU with a data cache in the Cortex-R5 group for memory regions configured as inner cacheable write-through in the CPU's MPU. It does not provide coherency for memory regions configured as cacheable write-back.

    I.e. if the memory containing the data to be CRC'ed is configured as cacheable write-back that may explain the issue, as on the failed iterations the input to the CRC might only be in the processor L1 data cache, i.e. not yet written back to SRAM.