CRC32 using Teensy4 DCP

Status
Not open for further replies.

klaasdc

Member
I was looking into using the DCP to efficiently calculate CRC32 checksums. However, I can't really find documentation on how to configure and use this peripheral. The "i.MX RT1060 Processor Reference Manual" has a single paragraph on it in section 7.5, p.182, and in the teensyduino headers there are some defines that refer to enable the clock to the DCP module, but that's it.

Eventually, I stumbled upon this repository: https://github.com/manitou48/teensy4/blob/master/dcptst.ino
The code works, but only for the supplied example with message length of 32. When I try to do a crc on longer sequences, it fails. But without the DCP register descriptions it is hard to follow why/what it is doing. Clearly, some more in-depth documentation must have been used to write this code?
Is there any separate doc's or app notes on the IMXRT DCP?

With a quick CRC check, I would like to verify at startup that some of the data or program sections are correct, in order to add a litle bit of fail-safe behavior.
 
That 2 year old code was likely written using the early 1062 Reference Manual - perhaps the NXP evaluation board and software tools had examples for reference?

Current version posted on PJRC.com - manual did suffer a re-org since that Beta - not sure what version was used above. See Technical Information here : pjrc.com/store/teensy40.html

There is this usable library installed with TeensyDuino - though not sure if it uses the hardware on T_4.x's : ...\hardware\teensy\avr\libraries\FastCRC\
 
The T4 hardware CRC is very limited, 32-bit fixed polynomial. It also has the flaw that input must be multiple of 4 bytes (it willl pad with nulls, if not), see
https://community.nxp.com/thread/506478
The SDK CRC example describes polymomial as "width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000". The SDK example with input "abcdbcdecdefdefgefghfghighijhijk" yields CRC of 0x7F046ADD, which matches the output of dcptst.ino mentioned above. The T4 hardware CRC runs at 382 MBs for a 16K input buffer.

You can configure a test using
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
and get the same result.

the FastCRC lib provides a collection of various CRC's, albeit table-driven for the Teensy 4.

The DCP documenation is only available under NDA. the dcptst.ino sketch was derived from NXP SDK examples.

Also see earlier T4 CRC discussions https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=197722&viewfull=1#post197722
 
Last edited:
The T4 hardware CRC is very limited, 32-bit fixed polynomial. It also has the flaw that input must be multiple of 4 bytes (it willl pad with nulls, if not), see
https://community.nxp.com/thread/506478
The SDK CRC example describes polymomial as "width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000". The SDK example with input "abcdbcdecdefdefgefghfghighijhijk" yields CRC of 0x7F046ADD, which matches the output of dcptst.ino mentioned above. The T4 hardware CRC runs at 382 MBs for a 16K input buffer.

You can configure a test using
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
and get the same result.

the FastCRC lib provides a collection of various CRC's, albeit table-driven for the Teensy 4.

The DCP documenation is only available under NDA. the dcptst.ino sketch was derived from NXP SDK examples.

Also see earlier T4 CRC discussions https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=197722&viewfull=1#post197722

Thanks to clarify. I think it could still be useful for my purpose. With those parameters and the online test it looks to correspond with the CRC32 MPEG-2 variant.
I am wondering though, if I double the message length to 64 in the example to e.g.

Code:
static const uint8_t message[] = "abcdbcdecdefdefgefghfghighijhijkabcdbcdecdefdefgefghfghighijhijk";
Then the output is 0xbf0fc452, while the online test gives 0x241003f8 :confused:

Also, in dcptst.ino on line 487 in DCP_HASH_Update(), there is:

Code:
void DCP_HASH_Update(dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
{
  bool isUpdateState;
  dcp_hash_ctx_internal_t *ctxInternal;
  size_t blockSize;

  ctxInternal = (dcp_hash_ctx_internal_t *)ctx;
  ctxInternal->fullMessageSize += inputSize;
  /* if we are still less than DCP_HASH_BLOCK_SIZE bytes, keep only in context */
  if ((ctxInternal->blksz + inputSize) <= blockSize)
  {
...
size_t blockSize is not initialized, so I assume always 0... Not sure how that is supposed to work :confused:
 
size_t blockSize is not initialized, so I assume always 0... Not sure how that is supposed to work :confused:

In DCP_HASH_Update() change declaration line to read: size_t blockSize = DCP_HASH_BLOCK_SIZE;
and for test string of 64 bytes sketch returns 241003f8

(github updated)
 
Last edited:
Status
Not open for further replies.
Back
Top