mirror of
https://github.com/marqs85/ossc.git
synced 2024-06-29 07:29:31 +00:00
266 lines
8.1 KiB
C
266 lines
8.1 KiB
C
|
/******************************************************************************
|
||
|
* *
|
||
|
* License Agreement *
|
||
|
* *
|
||
|
* Copyright (c) 2008 Altera Corporation, San Jose, California, USA. *
|
||
|
* All rights reserved. *
|
||
|
* *
|
||
|
* Permission is hereby granted, free of charge, to any person obtaining a *
|
||
|
* copy of this software and associated documentation files (the "Software"), *
|
||
|
* to deal in the Software without restriction, including without limitation *
|
||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
|
||
|
* and/or sell copies of the Software, and to permit persons to whom the *
|
||
|
* Software is furnished to do so, subject to the following conditions: *
|
||
|
* *
|
||
|
* The above copyright notice and this permission notice shall be included in *
|
||
|
* all copies or substantial portions of the Software. *
|
||
|
* *
|
||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
|
||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
|
||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
|
||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
|
||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
|
||
|
* DEALINGS IN THE SOFTWARE. *
|
||
|
* *
|
||
|
* This agreement shall be governed in all respects by the laws of the State *
|
||
|
* of California and by the laws of the United States of America. *
|
||
|
* Altera does not recommend, suggest or require that this reference design *
|
||
|
* file be used in conjunction or combination with any other product. *
|
||
|
******************************************************************************/
|
||
|
|
||
|
|
||
|
/**********************************************************************
|
||
|
*
|
||
|
* Filename: crc.c
|
||
|
*
|
||
|
* Description: Slow and fast implementations of the CRC standards.
|
||
|
*
|
||
|
* Notes: The parameters for each supported CRC standard are
|
||
|
* defined in the header file crc.h. The implementations
|
||
|
* here should stand up to further additions to that list.
|
||
|
*
|
||
|
*
|
||
|
* Copyright (c) 2000 by Michael Barr. This software is placed into
|
||
|
* the public domain and may be used for any purpose. However, this
|
||
|
* notice must not be changed or removed and no warranty is either
|
||
|
* expressed or implied by its publication or distribution.
|
||
|
**********************************************************************/
|
||
|
|
||
|
#include "crc.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Derive parameters from the standard-specific parameters in crc.h.
|
||
|
*/
|
||
|
#define WIDTH (8 * sizeof(crc))
|
||
|
#define TOPBIT (1 << (WIDTH - 1))
|
||
|
|
||
|
#if (REFLECT_DATA == TRUE)
|
||
|
#undef REFLECT_DATA
|
||
|
#define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
|
||
|
#else
|
||
|
#undef REFLECT_DATA
|
||
|
#define REFLECT_DATA(X) (X)
|
||
|
#endif
|
||
|
|
||
|
#if (REFLECT_REMAINDER == TRUE)
|
||
|
#undef REFLECT_REMAINDER
|
||
|
#define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
|
||
|
#else
|
||
|
#undef REFLECT_REMAINDER
|
||
|
#define REFLECT_REMAINDER(X) (X)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*********************************************************************
|
||
|
*
|
||
|
* Function: reflect()
|
||
|
*
|
||
|
* Description: Reorder the bits of a binary sequence, by reflecting
|
||
|
* them about the middle position.
|
||
|
*
|
||
|
* Notes: No checking is done that nBits <= 32.
|
||
|
*
|
||
|
* Returns: The reflection of the original data.
|
||
|
*
|
||
|
*********************************************************************/
|
||
|
static unsigned long
|
||
|
reflect(unsigned long data, unsigned char nBits)
|
||
|
{
|
||
|
unsigned long reflection = 0x00000000;
|
||
|
unsigned char bit;
|
||
|
|
||
|
/*
|
||
|
* Reflect the data about the center bit.
|
||
|
*/
|
||
|
for (bit = 0; bit < nBits; ++bit)
|
||
|
{
|
||
|
/*
|
||
|
* If the LSB bit is set, set the reflection of it.
|
||
|
*/
|
||
|
if (data & 0x01)
|
||
|
{
|
||
|
reflection |= (1 << ((nBits - 1) - bit));
|
||
|
}
|
||
|
|
||
|
data = (data >> 1);
|
||
|
}
|
||
|
|
||
|
return (reflection);
|
||
|
|
||
|
} /* reflect() */
|
||
|
|
||
|
|
||
|
/*********************************************************************
|
||
|
*
|
||
|
* Function: crcSlow()
|
||
|
*
|
||
|
* Description: Compute the CRC of a given message.
|
||
|
*
|
||
|
* Notes:
|
||
|
*
|
||
|
* Returns: The CRC of the message.
|
||
|
*
|
||
|
*********************************************************************/
|
||
|
crc
|
||
|
crcSlow(unsigned char const message[], int nBytes)
|
||
|
{
|
||
|
crc remainder = INITIAL_REMAINDER;
|
||
|
int byte;
|
||
|
unsigned char bit;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Perform modulo-2 division, a byte at a time.
|
||
|
*/
|
||
|
for (byte = 0; byte < nBytes; ++byte)
|
||
|
{
|
||
|
/*
|
||
|
* Bring the next byte into the remainder.
|
||
|
*/
|
||
|
remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
|
||
|
|
||
|
/*
|
||
|
* Perform modulo-2 division, a bit at a time.
|
||
|
*/
|
||
|
for (bit = 8; bit > 0; --bit)
|
||
|
{
|
||
|
/*
|
||
|
* Try to divide the current data bit.
|
||
|
*/
|
||
|
if (remainder & TOPBIT)
|
||
|
{
|
||
|
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
remainder = (remainder << 1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The final remainder is the CRC result.
|
||
|
*/
|
||
|
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||
|
|
||
|
} /* crcSlow() */
|
||
|
|
||
|
|
||
|
crc crcTable[256];
|
||
|
|
||
|
|
||
|
/*********************************************************************
|
||
|
*
|
||
|
* Function: crcInit()
|
||
|
*
|
||
|
* Description: Populate the partial CRC lookup table.
|
||
|
*
|
||
|
* Notes: This function must be rerun any time the CRC standard
|
||
|
* is changed. If desired, it can be run "offline" and
|
||
|
* the table results stored in an embedded system's ROM.
|
||
|
*
|
||
|
* Returns: None defined.
|
||
|
*
|
||
|
*********************************************************************/
|
||
|
void
|
||
|
crcInit(void)
|
||
|
{
|
||
|
crc remainder;
|
||
|
int dividend;
|
||
|
unsigned char bit;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Compute the remainder of each possible dividend.
|
||
|
*/
|
||
|
for (dividend = 0; dividend < 256; ++dividend)
|
||
|
{
|
||
|
/*
|
||
|
* Start with the dividend followed by zeros.
|
||
|
*/
|
||
|
remainder = dividend << (WIDTH - 8);
|
||
|
|
||
|
/*
|
||
|
* Perform modulo-2 division, a bit at a time.
|
||
|
*/
|
||
|
for (bit = 8; bit > 0; --bit)
|
||
|
{
|
||
|
/*
|
||
|
* Try to divide the current data bit.
|
||
|
*/
|
||
|
if (remainder & TOPBIT)
|
||
|
{
|
||
|
remainder = (remainder << 1) ^ POLYNOMIAL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
remainder = (remainder << 1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Store the result into the table.
|
||
|
*/
|
||
|
crcTable[dividend] = remainder;
|
||
|
}
|
||
|
|
||
|
} /* crcInit() */
|
||
|
|
||
|
|
||
|
/*********************************************************************
|
||
|
*
|
||
|
* Function: crcFast()
|
||
|
*
|
||
|
* Description: Compute the CRC of a given message.
|
||
|
*
|
||
|
* Notes: crcInit() must be called first.
|
||
|
*
|
||
|
* Returns: The CRC of the message.
|
||
|
*
|
||
|
*********************************************************************/
|
||
|
crc
|
||
|
crcFast(unsigned char const message[], int nBytes)
|
||
|
{
|
||
|
crc remainder = INITIAL_REMAINDER;
|
||
|
unsigned char data;
|
||
|
int byte;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Divide the message by the polynomial, a byte at a time.
|
||
|
*/
|
||
|
for (byte = 0; byte < nBytes; ++byte)
|
||
|
{
|
||
|
data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
|
||
|
remainder = crcTable[data] ^ (remainder << 8);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* The final remainder is the CRC.
|
||
|
*/
|
||
|
return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
|
||
|
|
||
|
} /* crcFast() */
|