- /*
- The CRC calculation unit mainly consists of a single 32-bit data register, which:
- is used as an input register to enter new data in the CRC calculator
- (when writing into the register) holds the result of the previous CRC calculation
- (when reading the register)
- Each write operation into the data register creates a combination of
- the previous CRC value and the new one
- (CRC computation is done on the whole 32-bit data word, and not byte per byte).
- The CPU is stalled during the computation, thus allowing back-to-back write accesses or
- consecutive write and read accesses, without having to insert software wait cycles.
- The CRC calculator can be reset to FFFF FFFFh with the RESET control bit in the CRC_CR register.
- This operation does not affect the contents of the CRC_IDR register
- POLY_USED_IN_STM32 0x04C11DB7
- #define CRC_INITIALVALUE 0xFFFFFFFF
- 1. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE); /* Enable CRC clock */
- 2.
- // 00 01 02 03 --> 0x03020100
- // 00 01 02 03 04 --> 0x03020100, 0x04000000
- // 00 01 02 03 04 05 --> 0x03020100, 0x05040000
- // 00 01 02 03 04 05 06 --> 0x03020100, 0x06050400
- //
- uint32_t stm32_hw_crc32(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte)
- {
- uint32_t last_data;
- uint32_t NumOfDWord = NumOfByte>>2;
- uint32_t NumOfTailByte = NumOfByte & 3 ;
- CRC_ResetDR();
- crc32 = CRC_CalcBlockCRC( (uint32_t *)pBuffer, NumOfDWord );
- switch ( NumOfTailByte )
- {
- case 0:
- return crc32;
- case 1:
- last_data = pBuffer[NumOfByte-1] << 24;
- break;
- case 2:
- last_data = *( (uint16_t *)(&pBuffer[NumOfByte-2]) );
- last_data <<= 16;
- break;
- case 3:
- last_data = *( (uint16_t *)(&pBuffer[NumOfByte-3]) );
- last_data <<= 8;
- last_data += pBuffer[NumOfByte-1]<<24;
- break;
- }
- return CRC_CalcCRC( last_data );
- }
- uint32_t stm32_sw_crc32_by_bit(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte)
- {
- uint32_t last_data;
- uint32_t NumOfDWord = NumOfByte>>2;
- uint32_t NumOfTailByte = NumOfByte & 3 ;
-
- while(NumOfDWord--)
- {
- crc32 = crc32 ^ *((unsigned long *)pBuffer);
- pBuffer += 4;
- for(int i=0; i<32; i++)
- {
- if (crc32 & 0x80000000)
- crc32 = (crc32 << 1) ^ POLY_USED_IN_STM32;
- else
- crc32 = (crc32 << 1);
- }
- }
-
- switch ( NumOfTailByte )
- {
- case 0:
- return crc32;
- case 1:
- last_data = pBuffer[0] << 24;
- break;
- case 2:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 16;
-
- break;
- case 3:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 8;
- last_data += pBuffer[2]<<24;
- break;
- }
- crc32 = stm32_sw_crc32_by_bit( crc32, (uint8_t *)&last_data, 4);
- return crc32;
- }
- // Nibble lookup table for 0x04C11DB7 polynomial
- const unsigned long sw_crc32_by_nibble_table[16] = {
- 0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,
- 0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
- 0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,
- 0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD
- };
- uint32_t stm32_sw_crc32_by_nibble(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte)
- {
- uint32_t last_data;
- uint32_t NumOfDWord = NumOfByte>>2;
- uint32_t NumOfTailByte = NumOfByte & 3 ;
-
- while(NumOfDWord--)
- {
- crc32 = crc32 ^ *((unsigned long *)pBuffer);
- pBuffer += 4;
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- crc32 = (crc32 << 4) ^ sw_crc32_by_nibble_table[crc32 >> 28];
- }
-
- switch ( NumOfTailByte )
- {
- case 0:
- return crc32;
- case 1:
- last_data = pBuffer[0] << 24;
- break;
- case 2:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 16;
-
- break;
- case 3:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 8;
- last_data += pBuffer[2]<<24;
- break;
- }
- crc32 = stm32_sw_crc32_by_nibble( crc32, (uint8_t *)&last_data, 4);
- return crc32;
- }
- unsigned long sw_crc32_by_byte_table[256] =
- {
- 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, // 0..3
- 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, // 4..7
- 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, // 8..B
- 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, // C..F
-
- 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9,
- 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
- 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011,
- 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
- 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
- 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
- 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81,
- 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
- 0xd4326d90, 0xd0f37027, 0**b056fe, 0xd9714b49,
- 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
- 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
- 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
- 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae,
- 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
- 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
- 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
- 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
- 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
- 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066,
- 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
- 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e,
- 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
- 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
- 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
- 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
- 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
- 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686,
- 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
- 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
- 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
- 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f,
- 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
- 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47,
- 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
- 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
- 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
- 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7,
- 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
- 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f,
- 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
- 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
- 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
- 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f,
- 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
- 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
- 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
- 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
- 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
- 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30,
- 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
- 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088,
- 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
- 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
- 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
- 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
- 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
- 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0,
- 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
- 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
- 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
- };
- uint32_t stm32_sw_crc32_by_byte(uint32_t crc32, uint8_t pBuffer[], uint32_t NumOfByte)
- {
- uint32_t last_data;
- uint32_t NumOfDWord = NumOfByte>>2;
- uint32_t NumOfTailByte = NumOfByte & 3 ;
-
- while(NumOfDWord--)
- {
- crc32 = crc32 ^ *((unsigned long *)pBuffer);
- pBuffer += 4;
- crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24];
- crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24];
- crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24];
- crc32 = (crc32 << 8) ^ sw_crc32_by_byte_table[crc32 >> 24];
- }
-
- switch ( NumOfTailByte )
- {
- case 0:
- return crc32;
- case 1:
- last_data = pBuffer[0] << 24;
- break;
- case 2:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 16;
-
- break;
- case 3:
- last_data = *( (uint16_t *)(&pBuffer[0]) );
- last_data <<= 8;
- last_data += pBuffer[2]<<24;
- break;
- }
- crc32 = stm32_sw_crc32_by_byte( crc32, (uint8_t *)&last_data, 4);
- return crc32;
- }
复制代码- unit uCRC32;
- interface
- uses
- Windows;
- function stm32_sw_crc32_by_byte(crc32 : DWORD;
- pBuffer : pbyte; NumOfByte : DWORD) : DWORD;
- function uCrc32_Demo : DWORD;
- implementation
- const
- sw_crc32_by_byte_table : array[0..255] of DWORD =
- (
- $00000000, $04c11db7, $09823b6e, $0d4326d9, // 0..3
- $130476dc, $17c56b6b, $1a864db2, $1e475005, // 4..7
- $2608edb8, $22c9f00f, $2f8ad6d6, $2b4bcb61, // 8..B
- $350c9b64, $31cd86d3, $3c8ea00a, $384fbdbd, // C..F
- $4c11db70, $48d0c6c7, $4593e01e, $4152fda9,
- $5f15adac, $5bd4b01b, $569796c2, $52568b75,
- $6a1936c8, $6ed82b7f, $639b0da6, $675a1011,
- $791d4014, $7ddc5da3, $709f7b7a, $745e66cd,
- $9823b6e0, $9ce2ab57, $91a18d8e, $95609039,
- $8b27c03c, $8fe6dd8b, $82a5fb52, $8664e6e5,
- $be2b5b58, $baea46ef, $b7a96036, $b3687d81,
- $ad2f2d84, $a9ee3033, $a4ad16ea, $a06c0b5d,
- $d4326d90, $d0f37027, $ddb056fe, $d9714b49,
- $c7361b4c, $c3f706fb, $ceb42022, $ca753d95,
- $f23a8028, $f6fb9d9f, $fbb8bb46, $ff79a6f1,
- $e13ef6f4, $e5ffeb43, $e8bccd9a, $ec7dd02d,
- $34867077, $30476dc0, $3d044b19, $39c556ae,
- $278206ab, $23431b1c, $2e003dc5, $2ac12072,
- $128e9dcf, $164f8078, $1b0ca6a1, $1fcdbb16,
- $018aeb13, $054bf6a4, $0808d07d, $0cc9cdca,
- $7897ab07, $7c56b6b0, $71159069, $75d48dde,
- $6b93dddb, $6f52c06c, $6211e6b5, $66d0fb02,
- $5e9f46bf, $5a5e5b08, $571d7dd1, $53dc6066,
- $4d9b3063, $495a2dd4, $44190b0d, $40d816ba,
- $aca5c697, $a864db20, $a527fdf9, $a1e6e04e,
- $bfa1b04b, $bb60adfc, $b6238b25, $b2e29692,
- $8aad2b2f, $8e6c3698, $832f1041, $87ee0df6,
- $99a95df3, $9d684044, $902b669d, $94ea7b2a,
- $e0b41de7, $e4750050, $e9362689, $edf73b3e,
- $f3b06b3b, $f771768c, $fa325055, $fef34de2,
- $c6bcf05f, $c27dede8, $cf3ecb31, $cbffd686,
- $d5b88683, $d1799b34, $dc3abded, $d8fba05a,
- $690ce0ee, $6dcdfd59, $608edb80, $644fc637,
- $7a089632, $7ec98b85, $738aad5c, $774bb0eb,
- $4f040d56, $4bc510e1, $46863638, $42472b8f,
- $5c007b8a, $58c1663d, $558240e4, $51435d53,
- $251d3b9e, $21dc2629, $2c9f00f0, $285e1d47,
- $36194d42, $32d850f5, $3f9b762c, $3b5a6b9b,
- $0315d626, $07d4cb91, $0a97ed48, $0e56f0ff,
- $1011a0fa, $14d0bd4d, $19939b94, $1d528623,
- $f12f560e, $f5ee4bb9, $f8ad6d60, $fc6c70d7,
- $e22b20d2, $e6ea3d65, $eba91bbc, $ef68060b,
- $d727bbb6, $d3e6a601, $dea580d8, $da649d6f,
- $c423cd6a, $c0e2d0dd, $cda1f604, $c960ebb3,
- $bd3e8d7e, $b9ff90c9, $b4bcb610, $b07daba7,
- $ae3afba2, $aafbe615, $a7b8c0cc, $a379dd7b,
- $9b3660c6, $9ff77d71, $92b45ba8, $9675461f,
- $8832161a, $8cf30bad, $81b02d74, $857130c3,
- $5d8a9099, $594b8d2e, $5408abf7, $50c9b640,
- $4e8ee645, $4a4ffbf2, $470cdd2b, $43cdc09c,
- $7b827d21, $7f436096, $7200464f, $76c15bf8,
- $68860bfd, $6c47164a, $61043093, $65c52d24,
- $119b4be9, $155a565e, $18197087, $1cd86d30,
- $029f3d35, $065e2082, $0b1d065b, $0fdc1bec,
- $3793a651, $3352bbe6, $3e119d3f, $3ad08088,
- $2497d08d, $2056cd3a, $2d15ebe3, $29d4f654,
- $c5a92679, $c1683bce, $cc2b1d17, $c8ea00a0,
- $d6ad50a5, $d26c4d12, $df2f6bcb, $dbee767c,
- $e3a1cbc1, $e760d676, $ea23f0af, $eee2ed18,
- $f0a5bd1d, $f464a0aa, $f9278673, $fde69bc4,
- $89b8fd09, $8d79e0be, $803ac667, $84fbdbd0,
- $9abc8bd5, $9e7d9662, $933eb0bb, $97ffad0c,
- $afb010b1, $ab710d06, $a6322bdf, $a2f33668,
- $bcb4666d, $b8757bda, $b5365d03, $b1f740b4
- );
- // 00 01 02 03 --> 0x03020100
- // 00 01 02 03 04 --> 0x03020100, 0x04000000
- // 00 01 02 03 04 05 --> 0x03020100, 0x05040000
- // 00 01 02 03 04 05 06 --> 0x03020100, 0x06050400
- //
- function stm32_sw_crc32_by_byte(crc32 : DWORD;
- pBuffer : pbyte; NumOfByte : DWORD) : DWORD;
- var
- i : DWORD;
- last_data : array[0..3] of byte;
- NumOfDWord : DWORD;
- NumOfTailByte : DWORD;
- begin
- NumOfDWord := NumOfByte shr 2;
- NumOfTailByte := NumOfByte and 3 ;
- for i := 0 to NumOfDWord-1 do
- begin
- crc32 := crc32 xor ( PDWORD( pbuffer ) )^;
- Inc( pbuffer, 4);
- crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24];
- crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24];
- crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24];
- crc32 := (crc32 shl 8) xor sw_crc32_by_byte_table[crc32 shr 24];
- end;
- if NumOfTailByte <> 0 then
- begin
- for i := 0 to 3 do
- last_data[i] := 0;
- if NumOfTailByte = 1 then
- begin
- last_data[3] := pBuffer^;
- end
- else if NumOfTailByte = 2 then
- begin
- last_data[2] := pBuffer^;
- Inc( pBuffer );
- last_data[3] := pBuffer^;
- end
- else
- begin
- last_data[1] := pBuffer^;
- Inc( pBuffer );
- last_data[2] := pBuffer^;
- Inc( pBuffer );
- last_data[3] := pBuffer^;
- end;
- crc32 := stm32_sw_crc32_by_byte( crc32, @last_data, 4 );
- end;
- result := crc32;
- end;
- function uCrc32_Demo : DWORD;
- var
- crc32 : DWORD;
- buffer : array[0..3] of DWORD;
- begin
- buffer[0] := $12345678;
- buffer[1] := $00000000;
- buffer[2] := $12345678;
- crc32 := stm32_sw_crc32_by_byte( $FFFFFFFF, @buffer, 12 );
- buffer[3] := crc32;
- crc32 := stm32_sw_crc32_by_byte( $FFFFFFFF, @buffer, 16 );
- result := crc32;
- end;
复制代码
|