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.

TMS570 CRC

Other Parts Discussed in Thread: HALCOGEN

I see in the Technical Reference Manual that the TMS570 includes a CRC peripheral. We are wondering whether we can use this to create a CRC and validate data packets transmitted across an SPI bus.

Is this a possible application of the CRC peripheral?

If so, do you have any sample code? (Halcogen does not appear to have support for the CRC module).

Thanks,

Richard

  • Hello Richard,

     

    in general the CRC module can be used to calculate a CRC over the received data stream, provided that the CRC for this data is know or was calculated with the same polynomial as the CRC module uses and was sent with the data.

     

    Depending on the data size care must be taken, because the CRC module treats a sub-64-bit write as a 64-bit value with leading 0's. For example if a byte write happened to address 0xFE000063 (CRCSIGREGL1 register), then register CRCSIGREGH1 and the 3 remaining bytes in CRCSIGREGL1 will be treated as 0's.

     

    Also in belows example the result is read as a 64-bit access into a long long variable. However due to the memory arrangement of the CRC registers the least significant word is stored at a lower address, thus defeating the big endian format. Basically both registers have to be reversed in code. This is just a hint to look out for...

     

    #define CRC_CTRL0         *(volatile unsigned int *)0xFE000000
    #define CRC_CTRL2         *(volatile unsigned int *)0xFE000010
    #define CRC_STATUS         *(volatile unsigned int *)0xFE000028
    #define CRC_SIGREGL1    *(volatile unsigned int *)0xFE000060
    #define CRC_SIGREGH1    *(volatile unsigned int *)0xFE000064
    #define CRC_SIGREG        *(volatile unsigned long long *)0xFE000060
    #define CRC_REGL1        *(volatile unsigned int *)0xFE000068
    #define CRC_REGH1        *(volatile unsigned int *)0xFE00006C

    const char endzero_array[10] = {0x01, 0x55, 0xFF, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x00};

    void main(void)
    {
    /* USER CODE BEGIN (3) */
        unsigned char count;
        unsigned long long result = 0;
       
        CRC_CTRL0 |= 0x00000001;        // reset CRC module
        CRC_CTRL0 &= 0xFFFFFFFE;
        CRC_CTRL2 |= 0x00000003;        // configure full CPU mode
       
        for(count = 0; count<10; count++)
        {
            CRC_SIGREGL1 = endzero_array[count];   
        }
       
        result = CRC_SIGREG;
    }

     

    Please let us know if this was helpful.

     

    Regards

    Frank

  • Hi Frank,

    Thanks for the information. We are sending the data over SPI from one TMS570 to another so as long as each uses the same algorithm I think we will be OK. Your sample looks very comprehensive and we will give it a try.

    Regards,

    Richard

  • Hi Frank,

    Just one last thing on this one; in order to use the CRC peripheral to generate a CRC for comms messages, the CRC polynomial must be seeded with a start value. If my reading of the TRM is correct, that means at the start of every CRC calculation, you need to set the peripheral to Data Capture Mode and write the seed (zero in the example below) to the PSA signature register.

    To extend your example, I assume you would use the following code:

    CRC_CTRL2 &= 0xfffffffc;  /* Set mode to Data Capture Mode */

    CRC_SIGREGL1 = 0;  /* Set seed to 0 */

    CRC_CTRL2 |= 3;  /* Set mode back to Full Cpu Mode */

    Regards,

    Richard

  • Hello Richard,

     

    yes your understanding is correct. Usually a different seed value is written than "0", but the user is free to use any value. If the PSA signature register should be reset to 0,  then another way to do it is to generate a software reset in control register 0 for this channel.

     

    Regards,

    Frank

  • Hi Frank,

    I want to prove the crc module in full-cpu mode and I have implemented your example and run the code.

    The value of the result register is = 0xAA179090000006BB.

    If the CRC it´s a data controller... what information has the result register?

    I mean, looking to the "result" value, the 64bits, what do I know?  Are the data of the array OK? ...

    David

  • David,

    the result is the checksum calculated over the data you've written to the signature register. In order to verify that the checksum is correct, you need to pre-calculate the checksum externally. The checksum is usually only calculated over know values, so it's easy to do the offline calculation after you've compiled your project.

    Regards,

    Frank

  • Hi David,

    I posted an algorithm here to precalculate the CRC http://e2e.ti.com/support/microcontrollers/tms570/f/312/p/104764/368714.aspx#368714.

    Unfortunately nobody has come up with a more elegant solution yet :(

    Regards,

    Richard

     

  • Hi,

    Thanks very much for the answers, I have added to the example program the "manually" calculation of the CRC and then compare them.

    To be honest the answer it´s not 100% completely correct, because if in the "automatic" calculation the crc was 0XAA179090000006BB in the manually way the value was swapped. 0x000006BBAA179090. I don´t know if this had happened to you too or if it is normal... But I´ll take the answer as correct.

    Even so I think the same of Richard; I think that this way to calculate the CRC it´s very inefficient. I´m not an expert on this, but I think that in the full-cpu way, if I want to do for example a SPI communication, apply the whole loop to certificate that both CRC are equal in all the data streams can affect extremely on the program speed.

    Anyway thanks again for your answers,

    David

  • Hi David,

    If you read the second post in this chain, you will see in the third paragraph that Frank states that the order of the registers defeats the big endian format for 64 bit numbers. In other words, the high and the low 32 bit parts of the answer are reversed which is exactly what you have discovered!

    I was hoping that someone with a mathematical bias might come up with a table based solution to calculate CRCs of this type; perhaps TI could commission somebody to do this work. Alternatively you could use a TMS570 at each end of your SPI link and then you no longer have a problem :)

    In our case we use the CRC engine to perform validation of our application image; PC software calculates the CRC for the image so the performance is less of an issue. However we also use the CRC engine when transferring data over SPI between two TMS570 processors.

    Regards,

    Richard

     

  • Hi, Rechard,

        There is a nearly same application in our project like your application in SPI.

        Redundant data is transmitted through SPI bus in multi-buffered mode with DMA in our project.

        But, Here is a question that  we do not know how to verify the end of a packet.

        Do you mind sharing your solution with this question?

        Thanks so much from the bottom of my heart  in advance.