1 year ago

#336052

test-img

TheShadow03

Universally CRC algorithm

I am trying to make an universally CRC algorithm that can be used for various lengths (e.g. 4, 5, 6, 8, 16, 32 bits).

I've manage to grasp the basics from Ross Williams site but when confronted with different implementation of various algorithms such as CRC-6/CDMA2000-A, on paper using the general algorithm and what my algorithm does it's the same thing, but not as it should be compared to a specific implementation of CRC-6.

Moreover I've compared my output to some sites such as this site and tried to adapt my code a little by how it shows the implementation on there, but I've come to the conclusion that, from my point of view, it's not working properly.

I'll post below my code and how an CRC-6 is constructed General CRC

typedef struct
{
    uint8 *CRC_Start_Address;
    uint32 CRC_Message_Length_In_Bytes;

    uint32 CRC_Polynomial;
    uint32 CRC_Initial_Remainder;
    uint32 CRC_Final_XOR_Val;

    uint32 CRC_Reflect_Data;
    uint32 CRC_Reflect_Remainder;

    uint32 CRC_Width_Of_Poly;
    uint32 CRC_Topbit; // = (1<<(CRC_Width_Of_Poly -1 )) ;
    uint32 CRC_Mask;
} CRC_Custom_Poly_Type;

CRC_Custom_Poly_Type CRC;

uint32 CRC_CrcCustomPolyTest(uint32 StartAddr, uint32 Length, uint8 SeedValue, uint8 Polynomial)
{
    CRC.CRC_Start_Address = (uint8 *)StartAddr;
    CRC.CRC_Message_Length_In_Bytes = (uint32)Length;
    CRC.CRC_Initial_Remainder = SeedValue;
    CRC.CRC_Polynomial = Polynomial;

    CRC.CRC_Reflect_Data = FALSE;
    CRC.CRC_Reflect_Remainder = FALSE;
    CRC.CRC_Final_XOR_Val = 0x0;

    CRC.CRC_Width_Of_Poly = 6;
    CRC.CRC_Topbit = 1U << (CRC.CRC_Width_Of_Poly - 1U);
    CRC.CRC_Mask = (1U << CRC.CRC_Width_Of_Poly) - 1U;

    uint8 addrIndex;
    uint32 byteIndex;
    uint8 copyByteIndex;

    if (CRC.CRC_Reflect_Data == TRUE)
    {
        CRC.CRC_Polynomial = reflect(CRC.CRC_Polynomial, CRC.CRC_Width_Of_Poly);
        CRC.CRC_Initial_Remainder = reflect(CRC.CRC_Initial_Remainder, CRC.CRC_Width_Of_Poly);
        CRC.CRC_Final_XOR_Val = reflect(CRC.CRC_Final_XOR_Val, CRC.CRC_Width_Of_Poly);
    }

    for (byteIndex = 0U; byteIndex < CRC.CRC_Message_Length_In_Bytes; byteIndex++)
    {
        // reflection
        copyByteIndex = CRC.CRC_Start_Address[byteIndex];

        if (CRC.CRC_Reflect_Data == TRUE)
        {
            CRC.CRC_Initial_Remainder ^= ((CRC.CRC_Start_Address[byteIndex]));

            for (addrIndex = 0; addrIndex < 8; ++addrIndex)
            {
                uint32 isSetAndReflection;
                if (CRC.CRC_Width_Of_Poly < 8)
                { 
                    isSetAndReflection = (CRC.CRC_Initial_Remainder & 1U) ^ (copyByteIndex & 0x01); 
                    copyByteIndex >>= 1U;
                }
                else
                {
                    isSetAndReflection = CRC.CRC_Initial_Remainder & 1U;
                }
                CRC.CRC_Initial_Remainder >>= 1U;
                if (isSetAndReflection)
                {
                    CRC.CRC_Initial_Remainder ^= CRC.CRC_Polynomial;
                }
                CRC.CRC_Initial_Remainder = CRC.CRC_Initial_Remainder & CRC.CRC_Mask;
            }
        }
        // no reflection
        else
        {
            if (CRC.CRC_Width_Of_Poly > 8U)
            {
                CRC.CRC_Initial_Remainder ^= (uint32)(CRC.CRC_Start_Address[byteIndex]) >> (CRC.CRC_Width_Of_Poly - 8U);
            }
            else
            {
                CRC.CRC_Initial_Remainder ^= ((CRC.CRC_Start_Address[byteIndex]));
            }

            for (addrIndex = 0; addrIndex < 8; ++addrIndex)
            {
                uint32 isSetNoReflection;
                if (CRC.CRC_Width_Of_Poly < 8U)
                {
                    isSetNoReflection = ((CRC.CRC_Initial_Remainder & CRC.CRC_Topbit) );//^ ((copyByteIndex & 0x80) >> (8U - CRC.CRC_Width_Of_Poly)));
                    //copyByteIndex <<= 1U;
                }
                else if (CRC.CRC_Width_Of_Poly == 8U)
                {
                    isSetNoReflection = CRC.CRC_Initial_Remainder & 0x80;
                }
                else // if (CRC.CRC_Width_Of_Poly > 8U)
                {
                    isSetNoReflection = CRC.CRC_Initial_Remainder & CRC.CRC_Mask;
                }
                CRC.CRC_Initial_Remainder <<= 1U;
                if (isSetNoReflection)
                {
                    CRC.CRC_Initial_Remainder ^= CRC.CRC_Polynomial;
                }
                CRC.CRC_Initial_Remainder &= CRC.CRC_Mask;
            }
        }
    }
    CRC.CRC_Initial_Remainder = CRC.CRC_Initial_Remainder ^ CRC.CRC_Final_XOR_Val;
    return CRC.CRC_Initial_Remainder;
    
}

uint32 reflect(uint32 StartAddr, uint32 Length)
{
    uint32 reflection = 0x00000000;
    uint8 bit;

    /*
     * Reflect the data about the center bit.
     */
    for (bit = 0; bit < Length; ++bit)
    {
        /*
         * If the LSB bit is set, set the reflection of it.
         */
        if (StartAddr & 0x01)
        {
            reflection |= (1U << ((Length - 1U) - bit));
        }

        StartAddr = (StartAddr >> 1U);
    }

    return (reflection);

} /* reflect() */

Input: 0x120000 Output: 0x08 Output to be expected: 0x30

CRC-6

/* Apply the basic 6-Bit CRC formula for the 2 bits left(slower): */
        /*     - Polynomial generator = X^6+X^5+X^2+X+1                   */
        /*     - Input bit = B                                            */
        /*     - New ShiftReg[0] = ShiftReg[5] XOR B                      */
        /*     - New ShiftReg[1] = (ShiftReg[5] XOR B) XOR ShiftReg[0]    */
        /*     - New ShiftReg[2] = (ShiftReg[5] XOR B) XOR ShiftReg[1]    */
        /*     - New ShiftReg[3] = ShiftReg[2]                            */
        /*     - New ShiftReg[4] = ShiftReg[3]                            */
        /*     - New ShiftReg[5] = (ShiftReg[5] XOR B) XOR ShiftReg[4]    */

Input: 0x120000 Output: 0x30

All I want to find out is:

  1. If is something wrong with my algorithm which does not correspond to the basic concept of CRC?
  2. Is there any possible way to generalize the algorithm in order to work on different widths ? if not why, even it's a different way form the hardware perspective?

c

crc

0 Answers

Your Answer

Accepted video resources