• AVR Freaks

AnsweredHot!CRC32 calculation using DMA (PIC32MX450F256H)

Author
toms
Junior Member
  • Total Posts : 118
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
2020/11/29 10:57:54 (permalink)
0

CRC32 calculation using DMA (PIC32MX450F256H)

Hi all,
 
Does anyone have any experience using this? Im stuck trying to reproduce a very simple example.
 
As a test, I am trying to get the CRC32 for 'hello' as a string. Every online tool, and every Python example I have been able to find will give me a value of 0x3610A686 for this, but I cannot reproduce it using the PIC32MX DMA and CRC modules.
 
Ive read a few suggestions of CRCing a few extra 0 bytes after the data itself, but after CRCing some extra zeroes (e.g. so the input data is a multiple of the number of polynomial bits, as was a suggestion I saw) it doesnt seem to be helping.
 
There have also been suggestions of using some value other than 0xFFFFFFFF as the initial/seed value, but I cant find any references to a value other than 0xFFFFFFFF, and unsure how to calculate this if it should be different.
 
Have tried with and without reflected inputs (BITO), although it seems that CRC32 uses reflected input data as one example tool I found does not produce the same result as everything else if I disable reflected input. The only thing I havent been able to find is a reflected output option, and this same tool also produces a different result if reflected output is disabled?
 
Information on the forum here so far is quite scarce, just one other thread but in the end that seemed to be revolving mostly around a 16 bit CRC.
 
Below is my code, would appreciate if someone is able to help out as I feel like Ive wasted a bit of my life trying to understand this already. I can implement a working crc32 function very easily in software, but would really like to try and do it using the hardware modules if possible.
 
Thanks!
 
void
main(void)
{
    uint32_t crc = 0;
    uint32_t crc2 = 0;
    const uint8_t crc_in[] = {'h', 'e', 'l', 'l', 'o'};
    const uint8_t crc_aug[] = {0, 0, 0, 0};
    
    IEC2CLR = _IEC2_DMA0IE_MASK; /* Disable int and clear flag */
    IFS2CLR = _IFS2_DMA0IF_MASK;
    
    DMACONbits.ON = 1; /* Enable DMA controller */
    
    DCRCDATA = 0xFFFFFFFF;
    DCRCXOR = 0x04C11DB7;
    DCRCCONbits.CRCAPP = 1; /* Append mode */
    DCRCCONbits.PLEN = (31 & 0x1f); /* 32 bit polynomial */
    DCRCCONbits.BITO = 1; /* Reflected input */
    DCRCCONbits.CRCEN = 1;
    
    DCH0CON = 0;
    DCH0ECON = 0;
    
    /* First do a CRC on the data itself */
    DCH0INT = 0;
    DCH0SSA = KVA_TO_PA((void *)&crc_in[0]);
    DCH0DSA = KVA_TO_PA((void *)&crc);
    DCH0SSIZ = 5;
    DCH0DSIZ = 4;
    DCH0CSIZ = 5;
    
    DCH0CONbits.CHEN = 1;
    DCH0ECONbits.CFORCE = 1;
    
    while (DCH0INTbits.CHBCIF == 0);

    crc2 = DCRCDATA ^ 0xFFFFFFFF;
    /*
     * Ideally at this point, crc2 contains the CRC32 for the input data.
     *
     * All other examples give me 0x3610A686, but in the above configuration I
     * get:
     *
     * DCRCDATA = 0xA8D1FCDC
     * crc2 = 0x572E0323
     *
     * with BITO = 0; or
     *
     * DCRCDATA = 0xB7B11BA8
     * crc2 = 0x484EE457
     *
     * with BITO = 1
     */
    
    /* Then do a CRC on some extra zeroes */
    uint8_t ctr = 0; /* Breakpoint here to check crc2 above */
    
    while (true) {
        DCH0INT = 0;
        DCH0SSA = KVA_TO_PA((void *)&crc_aug[0]);
        DCH0DSA = KVA_TO_PA((void *)&crc);
        DCH0SSIZ = 3;
        DCH0DSIZ = 4;
        DCH0CSIZ = 3;

        DCH0CONbits.CHEN = 1;
        DCH0ECONbits.CFORCE = 1;

        while (DCH0INTbits.CHBCIF == 0);

        crc2 = DCRCDATA ^ 0xFFFFFFFF;
        ctr++; /* Breakpoint here to check crc2 after each zero CRCd */
    }
    
    while (true);
    
    return;
}

#1
davea
Super Member
  • Total Posts : 585
  • Reward points : 0
  • Joined: 2016/01/28 13:12:13
  • Location: Tampa Bay FL USA
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/29 12:18:54 (permalink)
0
0xFFFFFFFF as the initial/seed value
allways
 
your changing to many thing at once
stick to what you know works 
(your software version works)
reflected does not sound normal
run your loop once and examine the results
and on your calculator  
xor them, swap hi word 
and see if you can get the results you want 
or any pattern that might lead you in the right direction
 
edit from the web 
also try feeding the crc module not using DMA

CRC32 hash for "hello" is "3d653119"

CRC32B hash for "hello" is "3610a686"

post edited by davea - 2020/11/29 12:39:30
#2
Jim Nickerson
User 452
  • Total Posts : 6841
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 07:17:20 (permalink)
#3
toms
Junior Member
  • Total Posts : 118
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 08:07:13 (permalink)
0
Hi Jim,
 
I had seen this post, but as a Mac user I am unable to run the software in the attached file.
#4
toms
Junior Member
  • Total Posts : 118
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 08:17:24 (permalink)
0
davea
0xFFFFFFFF as the initial/seed value
allways
 
your changing to many thing at once
stick to what you know works 
(your software version works)
reflected does not sound normal
run your loop once and examine the results
and on your calculator  
xor them, swap hi word 
and see if you can get the results you want 
or any pattern that might lead you in the right direction
 
edit from the web 
also try feeding the crc module not using DMA

CRC32 hash for "hello" is "3d653119"

CRC32B hash for "hello" is "3610a686"



99 times out of 100, trial and error will get me through and I rarely need to ask for help, but in this case it is not working so I was hoping someone could more definitively point out what I am doing wrong.
 
Maybe I just havent seen it yet, but I couldnt see a way to manually feed data into the CRC module like you seem to be able to do on other PICs.
#5
Jim Nickerson
User 452
  • Total Posts : 6841
  • Reward points : 0
  • Joined: 2003/11/07 12:35:10
  • Location: San Diego, CA
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 10:24:39 (permalink)
0
toms,
 
I wonder if you noticed in my post the comment about the Microchip DMA CRC example working ?
#6
toms
Junior Member
  • Total Posts : 118
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 13:46:51 (permalink)
4 (1)
Yes I do see that, but that is for a 16 bit CRC, whereas I am trying to do 32 bit.
 
I found a bit of information floating around about 16 bit CRCs, and a particular initial value to use other than 0xFFFF which would mean that the result of a CRC would come out "correctly", as in matching what a lot of online tools would produce.
 
No such luck yet with 32 bit though. Either the PIC CRC operates differently to all of the other CRC32 examples I can find, or Im doing something really dumb - just havent figured it out yet.
#7
andrew_aus
Starting Member
  • Total Posts : 13
  • Reward points : 0
  • Joined: 2011/08/10 22:10:05
  • Location: Australia
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/11/30 22:40:07 (permalink) ☼ Best Answerby toms 2020/12/01 01:35:03
5 (2)
You need to change the initialization of DCRCDATA from all ones to the magic number 0x46AF6449.

I got the number from this website: http://zorc.breitbandkatze.de/crc.html

Click on the 'CRC-32' button to reset the fields if necessary, then click the 'convert!' button.

You do want reflected input and you need to reflect the output as well.

In the section of code where you are crcing the 4 zeros you need to set DCH0SSIZ and DCH0CSIZ to 4, not 3.

The output needs to be reflected before the final xoring, like this:
 
    crc2 = 0;
    for (i = 0x80000000, j = 1; i; i >>= 1, j <<= 1)
    {
        if (crc & i) crc2 |= j;
    }
    crc2 ^= 0xFFFFFFFF;


#8
toms
Junior Member
  • Total Posts : 118
  • Reward points : 0
  • Joined: 2006/03/07 18:06:24
  • Location: London, UK
  • Status: offline
Re: CRC32 calculation using DMA (PIC32MX450F256H) 2020/12/01 01:35:06 (permalink)
0
You are the man! That is exactly what I needed.
 
I was having suspicions about needing a special number after seeing the same thing for some CRC16 examples, but couldnt for the life of me figure out how to compute it. I'll dig into the code of this website and see what it is doing, but this is now working.
 
Reversing the output was something I hadnt quite got around to trying, but thanks for confirming this is indeed a required step. Shame the PIC doesnt have a built in method to do this for you. :)
 
Never mind the loop of 3 at the end, thats just where I left the code before posting for help. At that moment in time I was working on the assumption that the input data should be a multiple of the polynomial length, but I had also tried 4 zeroes as well. I think the keys here were the special initial value and reversing the output at the end.
post edited by toms - 2020/12/01 01:53:04
#9
Jump to:
© 2021 APG vNext Commercial Version 4.5