Skip to main content
Associate
June 30, 2026
Question

How to restore STM32H7 CRC registers to continue CRC calculation

  • June 30, 2026
  • 1 reply
  • 41 views

Is there any doco or app note on how to save/restore a STM32H7 CRC calculation (e.g. breaking up long CRC calculation into separate segments that requires re-initialization of CRC HW between segments)?

1 reply

ST Technical Moderator
July 2, 2026

Hello ​@Propwash 

To continue a CRC calculation on STM32H7 across segments or after re‑initializing the CRC hardware, you can:

Before re-initialization / break:

  • Read the current CRC result from the CRC_DR register.
  • This value represents the intermediate CRC for the data processed so far.

After re-initialization of the CRC peripheral:

  • Write the saved intermediate CRC value into the CRC_INIT register.
  • This sets the starting (initial) CRC state for the next segment, effectively resuming the calculation where you left off.

Process the next data segment:

  • Feed the next chunk of data into the CRC peripheral as usual.
  • The final CRC result after all segments are processed will be in CRC_DR.

This save/restore via CRC_DR → CRC_INIT allows you to break a long CRC calculation into segments or survive a CRC peripheral reconfiguration while preserving continuity of the CRC computation.

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Saket_Om
PropwashAuthor
Associate
July 2, 2026

@Saket_Om

After I reset the CRC HW, I tried to set CRC_INIT to the value of the previous CRC_DR and continue but that did not produce the results I expected.

I created a utility in Nuttx running on Nucleo-H753ZI that reads/write the CRC registers and what follows is that while CRC’ng data consisting of 0x61626364 0x65666768, then resetting the CRC HW, setting initial value to the CRC_DR register value from CRC_DR of just 0x61626364, writing 0x65666768 to CRC_DR (to complete the CRC) and reading back CRC_DR, expecting result to match match (but it doesn’t):

NuttShell (NSH) NuttX-13.0.0-RC0
nsh> uname -a
NuttX 13.0.0-RC0 76838fa1b2 Jul  2 2026 13:41:40 arm nucleo-h753zi
nsh> pokecrc32 --help                                                           
pokecrc32: usage:                                                               
  -d    Turn on debug                                           
  -f     Force addresses to only be register names                              
  -b    Read/Write a byte                                       
  -h    Read/Write a short                                      
  -l     Read/Write a long                                                                    
  -r <addr>              Read at physical address <addr>                         
  -w <addr> <val>  Write <val> at physical address <addr>                  
Note: <addr> and <val> must be hex(w/o '0x' prefix)                              
      when reading a registers, '~' before register                             
      indicates to flip the bits. On write '~' before                           
      value indicates to flip its bits

                                        

Verify CRC clock is enabled (verify CRCEN is set in RCR_AHB4ENR)

nsh> pokecrc32 -r rcc_ahb4enr
580244e0 /l => 000800ff

Hard reset CRC (set/clear CRCRST in RCC_AHB4RSTR)

nsh> pokecrc32 -w rcc_ahb4rstr 80000 -w rcc_ahb4rstr 0
58024488 /l <= 00080000
58024488 /l <= 00000000

Reset/initialize CRC_CR to 0xe1(and read back to verify RESET clears):

  • Bit reverse output data
  • Bit reversal input data by word
  • 32-bit polynomial
  • Set reset bit

nsh> pokecrc32 -w crc_cr a1 -r crc_cr
58024c08 /l <= 000000a1
58024c08 /l => 000000a0


nsh> # Compute CRC of 'abcd' (expect raw 127d32ee; inverted ed82cd11)
nsh> pokecrc32 -w crc_dr 61626364 -l -r crc_dr -r ~crc_dr
58024c00 /l <= 61626364
58024c00 /l => 127d32ee
58024c00 /l => 127d32ee(~= ed82cd11)

Note /usr/bin/crc32 produces matching ed82cd11 for four byte 'abcd'

nsh> # Append 'efgh' (expect raw 5110d5af; inverted aeef2a50)
nsh> pokecrc32 -w crc_dr 65666768 -l -r crc_dr -r ~crc_dr
58024c00 /l <= 65666768
58024c00 /l => 5110d5af
58024c00 /l => 5110d5af(~= aeef2a50)

Note /usr/bin/crc32 produces matching aeef2a50 for eight byte 'abcdefgh'

Now Reset CRC HW, Intialize CRC_CR, and set CRC_INIT to result from previous
CRC_DR value for 'abcd'

nsh> # Hard Reset CRC
nsh> pokecrc32 -w rcc_ahb4rstr 80000 -w rcc_ahb4rstr 0
58024488 /l <= 00080000
58024488 /l <= 00000000
nsh> # Soft Reset CRC
nsh> pokecrc32 -w crc_cr a1 -r crc_cr
58024c08 /l <= 000000a1
58024c08 /l => 000000a0
nsh> # Set Initial value to CRC result of 'abcd'
nsh> pokecrc32 -w crc_init 127d32ee
58024c10 /l <= 127d32ee

Now feed in 'efgh' which should produce the same CRC_DR value as
previously:

nsh> # CRC of 'efgh' (expect raw 5110d5af; inverted aeef2a50)
nsh> pokecrc32 -w crc_dr 65666768 -l -r crc_dr -r ~crc_dr
58024c00 /l <= 65666768
58024c00 /l => 2abae3f7
58024c00 /l => 2abae3f7(~= d5451c08)

Note the resultant CRC does not match the expected aeef2a50.  Any idea why this doesn’t work as expected? Thanks in advance!