The above code can process 32KB/s in 6us on the H7 at 480 MHz.
Code: Select all
@micropython.viper def __stm_crc_16(self, data, size : int) -> int: # private ptr32(stm.CRC + stm.CRC_CR) = (1 << 3) | 1 # Reset and put into 1 byte per write mode. crc8 = ptr8(stm.CRC + stm.CRC_DR) d = ptr8(data) for i in range(size): crc8 = d[i] return ptr32(stm.CRC + stm.CRC_DR)
As the M4 does not support custom polynomials it cannot be used for the above. However, the F7 and H7 can. Note that if you want to feed the CRC hardware 16 or 32 bits at a time you have to byte reverse the data. It would be nice if MicroPython exposed __REV/__REV16 under the micropython module like how const is done for byte reversal, this would massively cut the processing time.
Code: Select all
if omv.board_type() == "H7": stm.mem32[stm.RCC + stm.RCC_AHB4ENR] = stm.mem32[stm.RCC + stm.RCC_AHB4ENR] | (1 << 19) # Enable CRC clock stm.mem32[stm.CRC + stm.CRC_POL] = 0x1021 elif omv.board_type() == "F7": stm.mem32[stm.RCC + stm.RCC_AHB1ENR] = stm.mem32[stm.RCC + stm.RCC_AHB1ENR] | (1 << 12) # Enable CRC clock stm.mem32[stm.CRC + stm.CRC_POL] = 0x1021
Anyway, I decided to post the above since I spent a while searching for answers on this and had to figure it out myself.
The M4 CRC hardware can only do CRCs for Ethernet packets.
The M7/H7 CRC hardware can do more flexible CRCs. However, they are only efficient for big endian data. I spent quite a bit of time trying every setting the hardware had along with flipping the polynomial around to avoid having to byte reverse the input to unlock 16-bit and 32-bit writes to the CRC hardware. However, byte-reversal is unavoidable. Until MicroPython has an easy byte reversal option it is faster to just feed the hardware one byte at a time that doing the reversal in python. Note the assembler does not support byte reversal opcodes.