Closed Thisora closed 2 years ago
Hi, this sounds strange - I've been using this code fine for quite a while, and on my computer/pico it's all good.
I've tested the crc32
program, Python3 binascii.crc32
, go crc32.ChecksumIEEE()
and they all agree.
Here is some test data:
const unsigned char random_bin[] = {
0x00, 0xfb, 0x51, 0x66, 0x26, 0xd4, 0xa5, 0xaf, 0xd6, 0x8b, 0x73, 0x7e,
0x3e, 0xe1, 0xf4, 0xef, 0x31, 0x06, 0x2a, 0x8d, 0xa0, 0xef, 0x3d, 0x0c,
0xe4, 0x2c, 0x3b, 0xd2, 0xa0, 0xcc, 0x59, 0x5c, 0x26, 0xbb, 0x9a, 0xe2,
0x91, 0x8d, 0x51, 0xed, 0x88, 0x17, 0x0b, 0xda, 0xea, 0xe6, 0xb9, 0xf8,
0x01, 0x65, 0x35, 0xe1, 0xb2, 0x4a, 0x72, 0x03, 0x28, 0x4f, 0x2a, 0x9e,
0x6b, 0x28, 0x2d, 0xf9
};
unsigned int random_bin_len = 64;
And a Pico C program:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/dma.h"
#include "hardware/flash.h"
#include "hardware/structs/dma.h"
// ptr must be 4-byte aligned and len must be a multiple of 4
static uint32_t calc_crc32(void *ptr, uint32_t len)
{
uint32_t dummy_dest, crc;
int channel = dma_claim_unused_channel(true);
dma_channel_config c = dma_channel_get_default_config(channel);
channel_config_set_transfer_data_size(&c, DMA_SIZE_32);
channel_config_set_read_increment(&c, true);
channel_config_set_write_increment(&c, false);
channel_config_set_sniff_enable(&c, true);
// Seed the CRC calculation
dma_hw->sniff_data = 0xffffffff;
// Mode 1, then bit-reverse the result gives the same result as
// golang's IEEE802.3 implementation
dma_sniffer_enable(channel, 0x1, true);
dma_hw->sniff_ctrl |= DMA_SNIFF_CTRL_OUT_REV_BITS;
dma_channel_configure(channel, &c, &dummy_dest, ptr, len / 4, true);
dma_channel_wait_for_finish_blocking(channel);
// Read the result before resetting
crc = dma_hw->sniff_data ^ 0xffffffff;
dma_sniffer_disable();
dma_channel_unclaim(channel);
return crc;
}
const unsigned char random_bin[] = {
0x00, 0xfb, 0x51, 0x66, 0x26, 0xd4, 0xa5, 0xaf, 0xd6, 0x8b, 0x73, 0x7e,
0x3e, 0xe1, 0xf4, 0xef, 0x31, 0x06, 0x2a, 0x8d, 0xa0, 0xef, 0x3d, 0x0c,
0xe4, 0x2c, 0x3b, 0xd2, 0xa0, 0xcc, 0x59, 0x5c, 0x26, 0xbb, 0x9a, 0xe2,
0x91, 0x8d, 0x51, 0xed, 0x88, 0x17, 0x0b, 0xda, 0xea, 0xe6, 0xb9, 0xf8,
0x01, 0x65, 0x35, 0xe1, 0xb2, 0x4a, 0x72, 0x03, 0x28, 0x4f, 0x2a, 0x9e,
0x6b, 0x28, 0x2d, 0xf9
};
unsigned int random_bin_len = 64;
int main() {
stdio_init_all();
while (1) {
sleep_ms(1000);
uint32_t crc = calc_crc32((void *)random_bin, random_bin_len);
printf("CRC Check: 0x%08x\n", crc);
}
}
On my Pico, it gives the following output:
...
CRC Check: 0xee728bc0
CRC Check: 0xee728bc0
...
Then with a binary version of the same data, and this Python program:
#!/usr/bin/env python3
import binascii
import sys
infile = sys.argv[1]
idata = open(infile, "rb").read()
crc = binascii.crc32(idata)
print(f'{hex(crc)}')
$ ./calc_checksum.py random.bin
0xee728bc0
And this go program:
package main
import (
"fmt"
"hash/crc32"
"io/ioutil"
"os"
)
func main() {
f, err := os.Open(os.Args[1])
if err != nil {
panic(err)
}
data, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
crc := crc32.ChecksumIEEE(data)
fmt.Printf("0x%08x\n", crc)
}
$ go run calc_checksum.go random.bin
0xee728bc0
And finally, with crc32
:
$ crc32 random.bin
ee728bc0
You can see that they all give the same result.
So, I'm afraid I can't reproduce your issue. Maybe you could try my example C program above on your Pico and tell me what result you get.
Humm i actually don't know. You are right your crc calculation is totally correct and i got this working just right now. Maybe i did something wrong the first time i tested it. I think the first time i tried my data was miss positioned in flash memory so my crc was wrong and i broke the calculation while trying to correct CRC.
Anyway, thank you for your answer.
I have problems with crc too... Checking...
First of all, thank you for your project. I had an issue with the CRC calculation. RP2040 CRC was wrong. First i had to remove the final XOR on the read of 'dw_dma-> sniff_data' (in method calc_crc32(...)). Finally look like this :
Second thing i had to change is in the python script (gen_imghdr.py). I had a lot of trubble but the biggest one was that the methode binascii.crc32() do not compute CRC the same as RP2040 DMA controller. I finally found that the correct CRC that RP2040 compute is the type CRC/MPEG-2. To do this i had to used the following function to compute CRC in python script:
I was also able to debug with vscode/openocd. If you want more information feel free to contact me.