原创 转贴:ATxmega128A1 software CRC that matches hardware

2010-2-19 02:36 2521 7 7 分类: MCU/ 嵌入式
/* 摘自avrfreaks

 * The Xmega manual Rev G lists the CRC Polynomial


 * as:  x^24 + 4x3 + 3x +1.


 *


 * Based on some untested code supplied by avr(at)atmel.com,


 * I believe the correct Polynomial is:


 * x^19 + x^4 + x^3 + x^1 + 1


 *


 * At any rate after cleaning up their code issues, the following C


 * code generates the same values as the XMega 128A1 hardware.


 *


 * Any math grues out there than can tells how


 * strong this non-standard Polynomial is?


 *


 * The hardware initializes the CRC register to all zeros,


 * rather than all ones.  This can lead to missing the


 * detection of inserted leading zeros.


 *


 * - Bob Paddock


 *


 */





#include <stdint.h>


#include <avr/io.h>


#include <util/delay.h>





#include "sp_driver.h"





static inline LED_GREEN_TOGGLE( void )


{


  /* Put your LED code here */


}





static inline LED_RED_TOGGLE( void )


{


  /* Put your LED code here */


}





#define CRC32_POLY (0x0080001BUL) /* Polynomial for use with Xmega 'A' devices */





/* This CRC Routine is the corresponding routine implemented in Xmega hardware: */


uint32_t CRC_Reference( uint32_t startWord_u32, uint32_t endWord_u32 )


{


   uint32_t addr_u32, data_reg_u32, help_a_u32, help_b_u32;


   uint32_t crc_reg_u32 = 0;





   for( addr_u32 = startWord_u32; addr_u32 <= endWord_u32; addr_u32 += 2 )


   {


      help_a_u32  = crc_reg_u32 << 1;


      help_a_u32 &= 0x00FFFFFEUL; /* Always act as 24-bit variable */





      help_b_u32  = crc_reg_u32 & (1UL << 23);





      if( help_b_u32 > 0 )


          {


            help_b_u32 = 0x00FFFFFFUL;


          }





      data_reg_u32 = SP_ReadWord( addr_u32 );





      crc_reg_u32 = (help_a_u32 ^ data_reg_u32) ^ (help_b_u32 & CRC32_POLY);


      crc_reg_u32 = crc_reg_u32 & 0x00FFFFFFUL;


   }





   return( crc_reg_u32 );


}





int main( void )


{


  uint32_t crc_u32;





  crc_u32 = SP_BootCRC();


  if( crc_u32 != CRC_Reference( BOOT_SECTION_START, (BOOT_SECTION_END-1) ) ) /* END-1 is due to use of words, not bytes */


    {


      for(;;)/* Boot CRC missmatch */


        {


          _delay_ms(500.0);


          LED_GREEN_TOGGLE();


        }


    }





  crc_u32 = SP_ApplicationCRC();


  if( crc_u32 != CRC_Reference( APP_SECTION_START, (APP_SECTION_END-1) ) ) /* END-1 is due to use of words, not bytes */


    {


      for(;;)/* Application CRC missmatch */


        {


          _delay_ms(500.0);


          LED_RED_TOGGLE();


        }


    }





  /* CRCs match if we get here */


}




文章评论0条评论)

登录后参与讨论
我要评论
0
7
关闭 站长推荐上一条 /2 下一条