This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Concerto uCRC example

Other Parts Discussed in Thread: CONTROLSUITE

Hello,

Is there any example or library that uses the uCRC module?

Thanks,

Max

  • Hi Max,

    your post is old and you probably have solved your questions... but I'm now on that issue.

    In the ControlSuite you can find in the driverlib folder some API functions for the module. It is simple to use, indeed. You may wish to modify the calculation function  without clearing the result automatically to be able to get a checksum for data blocks.

    Now I have some questions on the calculation of a CRC-32 with the API function.
    For a test-string of "123456789" the result is 0x89A1897F (Hex). So the following parameters are used for calculation:

    Width : 32
    Poly : 0x04C11DB7
    Init : 0x0
    ReflectionIn: FALSE
    ReflectionOut :FALSE
    XorOut : 0x0

    Is there a way to modify the API function or the uCRC unit in a way to calculate the CRC-32 in the following way:

    Width : 32
    Poly : 0x04C11DB7
    Init : 0xFFFFFFFF
    ReflectionIn: TRUE
    ReflectionOut : TRUE
    XorOut : 0xFFFFFFFF

    This standard is commonly used on PC programs (ZIP etc.). The result for the test string is 0xCBF43926.

    I will check myself to do so but maybe someone has already done it and can help me right away?

    Regards,
    Stefan



  • Hi,

    I have modified the API functions of the uCRC-module to calculate a CRC-32. Maybe someone is interested to use these. So here are the attached files:

    /*!*****************************************************************************
      \file     ucrc32.c                                                            
                                                                                    
      \remarks  API for calculation of CRC-32 with uCRC-Module of ARM M3            
                                                                                    
      \author   Stefan B�chner, M&P GmbH 2013                                       
      \date     April 2013                                                          
    ********************************************************************************/
    
    #include "basetype.h"
    #include "inc/hw_ucrc.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/debug.h"
    #include "ucrc32.h"
    
    /*******************************************************************************
     *  local definitions                                                           
     *******************************************************************************/
    
    //! Remap address for CRC calculation
    #define UCRC_REMAP_ADDRESS(x)    ((unsigned long) x | 0x04000000)
    
    //! CRC type defined in UCRC Config Register: CRC32 (Polynomial = 0x04C11DB7)
    #define UCRC_CONFIG_CRC32         0x00000003L
    //! Initial value
    #define UCRC32_INITIAL_VALUE      0xFFFFFFFFL
    //! Initial value
    #define UCRC32_FINAL_XOR_VALUE    0xFFFFFFFFL
    //! Reflect data bytes
    #define UCRC32_REFLECT_DATA_BYTES         TRUE
    //! Reflect CRC result before Final XOR
    #define UCRC32_REFLECT_BEFORE_FINAL_XOR   TRUE
    
    /*******************************************************************************
     *  private function prototypes - called intern only                            
     *******************************************************************************/
    static inline UINT32 crc_reflect(UINT32 data, UINT8 data_len);
    
    /*******************************************************************************
     *  public functions                                                            
     *******************************************************************************/
    
    /*******************************************************************************
    * \fn void UCRC32_Reset(void)                                                   
    ********************************************************************************/
    /*!\param     -                                                                 
    *                                                                               
    *  \remarks   Initialize the uCRC-Module for calculation of CRC-32, set the     
    *             initial value                                                     
    *                                                                               
    *  \retval    -                                                                 
    ********************************************************************************/
    void UCRC32_Reset(void)
    {
      // Config the uCRC Module to CRC-32 polynom.
      HWREG(UCRC_BASE + UCRC_O_CONFIG) = UCRC_CONFIG_CRC32;
      // Set the result register to initiall value.
      HWREG(UCRC_BASE + UCRC_O_RES) = UCRC32_INITIAL_VALUE;
    }
    
    /*******************************************************************************
    * \fn void UCRC32_Update(UINT8* pData, UINT32 numBytes)                         
    ********************************************************************************/
    /*!\param     pData - pointer to data which has to be enumerated                
    *  \param     numBytwes - Number of bytes to be enumerated
    *                                                                               
    *  \remarks   Update the crc value in the UCRC result register with new data    
    *                                                                               
    *  \retval    -                                                                 
    ********************************************************************************/
    void UCRC32_Update(UINT8* pData, UINT32 numBytes)
    {
      UINT32 ulTemp;
      UINT8 byteBuf;
      UINT8* pByteBuf;
    
      // uCRC only calculates on reads from a re-mapped space of memory,
      // so we need to remap the address before we start calculation.
      pByteBuf = (unsigned char *)UCRC_REMAP_ADDRESS(&byteBuf);
    
      // Read the buffer while calculating CRC
      while(numBytes--)
      {
      #ifdef UCRC32_REFLECT_DATA_BYTES
        // reflected data byte
        byteBuf = crc_reflect(*pData++, 8);
      #else
        // plain data byte
        byteBuf = *pData++;
      #endif
        ulTemp = HWREGB(pByteBuf);
      }
      ulTemp = ulTemp; // prevent compiler warning
    }
    
    
    /*******************************************************************************
    * \fn UINT32 UCRC32_Finalize(void)                                              
    ********************************************************************************/
    /*!\param     -                                                                 
    *                                                                               
    *  \remarks   Calculate the final crc-32 value                                  
    *                                                                               
    *  \retval    CRC-32 of enumerated data used by the Update-function             
    ********************************************************************************/
    UINT32 UCRC32_Finalize(void)
    {
      UINT32 crc32;
      
    #ifdef UCRC32_REFLECT_BEFORE_FINAL_XOR
      // reflected result from uCRC result register
      crc32 = crc_reflect(HWREG(UCRC_BASE + UCRC_O_RES), 32);
    #else
      // plain result from uCRC result register
      crc32 = HWREG(UCRC_BASE + UCRC_O_RES);
    #endif
      // XOR the result with 
      return (crc32 ^ UCRC32_FINAL_XOR_VALUE) & 0xffffffff;
    }
    
    /*******************************************************************************
     *  private functions                                                           
     *******************************************************************************/
    
    /*******************************************************************************
    * \fn static inline UINT32 crc_reflect(UINT32 data, UINT8 data_len)             
    ********************************************************************************/
    /*!\param     data      - The data word to be reflected.                        
    *  \param     data_len  - The width of \a data expressed in number of bits.     
    *                                                                               
    *  \remarks   Reflect all bits of a data word of data_len bytes.                
    *                                                                               
    *  \retval    the reflected data                                                
    ********************************************************************************/
    static inline UINT32 crc_reflect(UINT32 data, UINT8 data_len)
    {
      UINT8 i;
      UINT32 ret;
    
      ret = data & 0x01;
      for (i = 1; i < data_len; i++)
      {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
      }
      return ret;
    }
    

    4111.ucrc32.h

    Attention: I haven't checked the result of all possible compiler switches!

    The functions for reflection the data I have used the code form pycrc (www.tty1.net). This is a good source to understand the difference in the crc algorithms.
    Another good website with an online calculator is http://www.zorc.breitbandkatze.de/crc.html.

    Now the bad thing: For calculation of a 800kByte binary file (reading data blocks of 4096 Bytes from USB as a MSC host) it  takes 21 seconds while using the table driven algorithm of the pycrc code only takes 5,4 seconds! This is because the data reflection has to be done by software and can't be done in the uCRC module while the table driven algorithm includes the data reflection already. So I won't use the uCRC module in my application. Too bad the TI developers didn't have that in mind.

    Or am I missing something?

    Best regards,
    Stefan