Other Parts Discussed in Thread: CONTROLSUITE
Hello,
Is there any example or library that uses the uCRC module?
Thanks,
Max
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.
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;
}
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