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.

TMS570LS3137 CRC on 8 bit data

Other Parts Discussed in Thread: HALCOGEN

Hi,

I have 2, hopefully, short questions on the CRC module.

1. Am I right in saying the Polynomial cannot be changed?

2. I am trying to get the CRC module working in FULL_CPU mode on blocks of data of different lengths, so a byte wise CRC would seem to be the best way to go. When I look at the HalCoGen generated code the crcSignGen function takes as a parameter a pointer to a structure that contains a pointer to 64 bit data.

In order to do a CRC on 8 bit data do I have to load each byte in turn into the SIGREGL1 register or do I concatenate the bytes into a 64 bit variable, blanking whatever is left over, and operate it as a 64 bit? I have tried both ways and can't get the results to tie up with some online calculators.

Regards

Andy

  • Hello:

    We have received your post and will get back to you soon.

    Regards.

  • Hi Andy,

      1. you are correct that the polynomial can not be changed.

      2. The CRC computation is always based on a 64-bit data chunk. If you simply write a 8-bit data to the PSA_SIGREGL1, what will happen is that the unselected bytes are padded with zeros  For example, if you write 0xFF to bit7-0 of the PSA_SIGREGL1, the data that is taken for CRC computation is still  a 64-bit data as in 0x00000000_000000FF. Basically, doing a byte write with data 0xFF to the PSA_SIGREGL1 will produce the same signature as if you wrote 64-bit to both PSA_SIGREGH1 and PSA_SIGREGL1 at once with the value 0x00000000_000000FF,

  • Hi Charles,

    thanks for your answer. That was very helpful.

    You don't know of a tool (maybe an online calculator or a standalone app) that I could use to verify the result? I'm struggling to find one that outputs a 64 bit result.

    Regards

    Andy

  • Hi Andy,

      You may try pycrc at the below link.

    http://www.tty1.net/pycrc/index_en.html

     

  • Hi David,

    thanks for that. I did look at that one, but I can't get the results to tie up.

    I'm putting in dummy data of 123456789 (= 0x75BCD15), selecting 64 bit CRC order, a polynomial of 000000000000001B, initial and final values of 0, direct or non-direct doesn't seem to make a difference, the reverse data checkbox is unchecked (I presume that's for little endian data) and reverse CRC result before XOR is also unchecked (Frankly I don't know what this does).

    When I hit compute with the hex value I get a result of:

    293A29388CEC9A7 (hex)

    the same test with denary (decimal) input gives:

    E4FFBEA588933790

    run this test value as a uint64 through the CRC module on the TMS570 using the HalCoGen generated functions crcSignGen  and crcGetPSASig returns a value of:

    0x468EEEC700000000

    I don't know how to make sense of that. I must be doing something wrong somewhere.

    Thanks

    Andy

  • Hello Andy,

      I use pycrc and get the same signature as from TMS570 CRC. I entered 75bcd15 as the input hexstring and I get 0x468eeec7 as the signature output which is matching the hardware. Maybe you missed the --check_hexstring switch.

  • Hi Charles,

    thanks for that. That worked! I also found out what went wrong with the online checker, it was treating the input data as ASCII, so 1234.. becomes 0x31, 0x32, 0x33 etc. Then it ties up.

    I have just one more question on this subject. How do I get the DMA to input 8 bit data if it's expecting 64 bit data?

    Regards

    Andy

  • Hello Andy,

      CRC module does not know where the input data is coming from; either CPU or DMA. So what I explained about the data padding when the CPU write size is not 64-bit will also apply to the DMA. For example, if you setup the DMA read element size as 64-bit and the write element size as 8 bit, then the DMA will read from the source memory in one 64-bit bus transaction. Since the destination element size is configured for 8-bit then the DMA will do a so-called "unpacking" operation by breaking the 64-bit read data into eight 8-bit data. Depending on how you setup the addressing mode as in either the fixed address or increment address mode, the DMA will write to the PSA_SIGREGL1 register 8 times with 8 different 8-bit data.

      Suppose the 64-bit data read from the source memory is 0x1122334455667788 and you setup the destination element size as 8-bit and the address mode is fixed addressing mode and also the destination address is 0xFE00_0063. Note the 0x63 offset address will address the LSB of the PSA_SIGREG1 since the DMA works in big endianism mode only. With the above setup the DMA will write to the address location 0xFE00_0063 eight times and each time the CRC module will automatically pad the other 56 bits with zeros. So from the CRC computation point of view, the CRC will calculate the signature based on the below eight 64-bit input data:

    0x0000000000000011

    0x0000000000000022

    0x0000000000000033

    0x0000000000000044

    0x0000000000000055

    0x0000000000000066

    0x0000000000000077

    0x0000000000000088

    0x0000000000000011

    0x0000000000000011

     Of course, if you set the DMA destination element size with 64-bit then there is no padding. The DMA will write to the PSA_SIGREGH1 and PSA_SIGREGL1 simultaneously with the data 0x55667788 and 0x11223344 only one time.  And the signature will be very different from the earlier example where the destination element size is setup for 8-bit.

  • Sorry, a bit of copy and paste on the first example. The eight 64-bit data taken for the CRC computation are:

    0x0000000000000011

    0x0000000000000022

    0x0000000000000033

    0x0000000000000044

    0x0000000000000055

    0x0000000000000066

    0x0000000000000077

    0x0000000000000088

     

  • Thanks, that answers that question perfectly!

    However, I'm still having some problems. When I run a test with the data 123456789, it works and the result ties up with that produced by pycrc, but when I change the data set to a 2 element array of uint64s each with a value of 0x0102030405060708 the results differ. I chose this value so that all 64 bits are used.

    If you take into account the long swap the two results differ by the least significant byte on each long.

    The code looks like this:

        DataLength = sizeof(TestData);
        DataLength >>= 3;   // divide by 8
        
        CRCstruct.mode = CRC_FULL_CPU;
        CRCstruct.crc_channel = CRC_CH1;
        CRCstruct.src_data_pat = TestData;
        CRCstruct.data_length = DataLength;
        
        crcChannelReset( crcREG, CRCstruct.crc_channel );
        crcSignGen( crcREG, &CRCstruct );
        CRCTest = crcGetPSASig( crcREG, CRCstruct.crc_channel );

    the value of CRCTest after this point is:  Hex:0x21C290F15CBFE714

    which is the same except for F1 and 14.

    Any idea what could be going wrong?

    Regards

    Andy

  • Hello Andy,

      It has to do with the endianism. Please take a look with the below example on the input string. The output signature matches with the TMS570 CRC.

  • Thanks for that.

    Being as we don't know the length of the data that will require the CRC it would be best to read it as 8 bit data. Following what you had done earlier I tried putting that into the registers as 64 bit (padded out with zeros), but it didn't match the output from pycrc or others.

    However, I found that if I pad it out to 32 bits and write it into the PSA_SIGREGL1 register, then it works.

    Ultimately we will want to use DMA, but I haven't got this working yet. I presume that writing it as 32 bits will be the best way to go for that.

    Regards

    Andy

  • Hi Andy,

      I created a project that uses both Full-CPU mode and the DMA. In this project the data array is stored in the a1.asm. I first compare the Full-CPU signature against the linker generated CRC signature. Later I use the DMA to transfer 16 8-bit data to the PSASIGL1 register and compare against the pycrc generated signature and they all match. Please find the project below and and also  the screenshot from pycrc.

    7462.CRC_DMA.zip

    The array stored in the a1.asm is:

    word1 .word 0x11223344,0x55667788,0x99aabbcc,0xddeeff12

    I have below DMA setup:

    dma_config.SADD = (uint32_t)my_crc_table_for_a1.recs[0].addr;

    dma_config.DADD = (uint32_t)&(crcREG->PSA_SIGREGL1)+3;

    dma_config.CHCTRL = 0;

    dma_config.FRCNT = 1;

    dma_config.ELCNT = 16;

    dma_config.ELDOFFSET = 0;

    dma_config.ELSOFFSET = 0;

    dma_config.FRDOFFSET = 0 ;

    dma_config.FRSOFFSET = 0;

    dma_config.PORTASGN = 4;

    dma_config.RDSIZE = ACCESS_8_BIT;

    dma_config.WRSIZE = ACCESS_8_BIT;

    dma_config.TTYPE = FRAME_TRANSFER;

    dma_config.ADDMODERD = ADDR_INC1;

    dma_config.ADDMODEWR = ADDR_FIXED;

    dma_config.AUTOINIT = AUTOINIT_OFF;

    The CRC signature produced by using DMA transfer has the same signature as below calculated by pycrc.

     

     

  • Hi Charles,

    I agree, that works. Thanks for that.

    There is just one thing that confuses me. The value you write into DADD, doesn't that have to be on a 4 byte boundary, or to put the question another way, which register are you addressing here?

    I have been trying to get DMA working for some time, is it the call to dmaSetChEnable(0,DMA_SW) that initiates the transfer?

    Regards

    Andy

  • Hi Andy,

      I understand this may be confusing to some users. Let me explain. First, the DMA always operates in Big Endian mode. This is the same as the TMS570 CPU. Let's think how the CPU would address a particular byte in the PSASIGL1 register. Since the CPU and DMA operate in big endian mode, it means that if CPU/DMA wants to write to the MSB (bit31:24) then it needs to provide a byte address with offset 0. If CPU wants to write to the LSB of the register (bit7:0) then it needs to provide a byte address with the offset 3. This is only valid if you are attempting to perform a byte write. If you are doing a word write then the word address is sufficient.

      Since the DMA transfer is configured with the write element size of 8-bit and the address mode is fixed addressing mode, then this is the reason that the DADD needs to be 0xFE00_0063. Bear in mind that you are doing a 8-bit transfer which is a byte write and you want to write to the LSB at bit7:0 of the register. If you put 0xFE00_0060 into the DADD then the DMA will write to the MSB at bit31:24. Remember that I talk about padding with zeros? If you setup the DADD with 0xFE00_0060 and the DMA is also setup for 8-bit write size and fixed address mode, then the CRC would pad zeros to the entire 32bits of the PSASIGH1 and zeros on bits23:0 of the PSASIGL1. Let's say the data is "FF" that you want to transfer. The CRC will compute the signature based on a 64-bit input value of 0x00000000_FF00000000. The signature generated by this input data will be different from the DADD=0xFE00_0063 where the input data would have been 0x00000000_000000FF.  

     To answer your second question, yes the dmaSetChEnable(0, DMA_SW) is used to generate a s/w request on channel 0. Upon completion of the specified transfer, the corresonding bit in the SWCHENA will be cleared. This is why I poll the SWCHENA to know when the DMA has finished the transfer before reading the CRC signature.

     

     

     

    Second, the write transfer size is setup for 8-bit as this is your desired size since you said that you don't know the length of the data array. Wi

  • Please ignore tha last incomplete sentence at the bottom of the post.

  • Sorry I need to clarify something again.

    I need to swap wherever I have MSB with LSB and LSB with MSB as below.

    Since the CPU and DMA operate in big endian mode, it means that if CPU/DMA wants to write to the LSB(bit31:24) then it needs to provide a byte address with offset 0. If CPU wants to write to the MSB of the register (bit7:0) then it needs to provide a byte address with the offset 3.

  • I get it, but I think your first explanation was clearer than the second!

    The base address of a register (that is big endian) will be the MS byte. Because the registers of the DMA are ordered Low then High. The byte order, in increasing addresses is:

    3 2 1 0 7 6 5 4.

    So to access byte 0, the LS byte, I need an offset of 3.

    You may have missed my second question. What triggers the DMA transfer?

    Regards

    Andy

  • Hi Andy,

      I thought I answered your second question in the below paragraph. When you write to the corresponding bit in the SWCHENA register it will generate a s/w request on the corresponding channel and initiate the DMA transfer for that channel.

    "To answer your second question, yes the dmaSetChEnable(0, DMA_SW) is used to generate a s/w request on channel 0. Upon completion of the specified transfer, the corresonding bit in the SWCHENA will be cleared. This is why I poll the SWCHENA to know when the DMA has finished the transfer before reading the CRC signature."

      Also I guess my first explanation is clearer than the second. Accoding to the the Big-End definition:

      "Big-endian systems store the most significant byte of a word in the smallest address and the least significant byte is stored in the largest address".