zoukankan      html  css  js  c++  java
  • STM32 CRC32 ( Delphi )

    /*
    
    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, 0xddb056fe, 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;

  • 相关阅读:
    必须了解的经典排序算法整理
    浅谈Code Review
    NOIP2018提高组省一冲奖班模测训练(六)
    NOIP2018提高组省一冲奖班模测训练(五)
    NOIP2018提高组金牌训练营——动态规划专题
    poj 3074
    搜索中的剪枝
    bitset骚操作
    NOIP 2017 宝藏
    prim求最小生成树
  • 原文地址:https://www.cnblogs.com/shangdawei/p/3049789.html
Copyright © 2011-2022 走看看