0

I would like some help as I seem to be unable to calculate the CRC for a single byte, let alone an array of bytes.

Below is the test code that I have been trying to get work. Please note that I used the code from this post, and the example with the array of chars works, but I need to be able to adapt this to work for an array of uint8_t.

When going through the fundamentals of CRC, this seems like it should work but I may be mistaken.

I have been trying to validate the function by checking the outputted remainder (crc) using this site.

If someone could kindly identify where the issue is coming round which is leading to the wrong CRC value being calculated, and educate me as to why this is happening, that would be highly appreciated!

#include <cstdint>
#include <iostream>

// Below 2 functions take from 
// https://stackoverflow.com/questions/59486262/issues-calculating-crc16-mcrf4xx-for-more-than-1-byte

int16_t Utils_CRC16_MCRF4XX( uint16_t Crc, uint8_t Byte )
{
    Crc ^= Byte ;

    for( uint8_t i = 0; i < 8; i++ )
    {
        Crc = (Crc & 0x0001) != 0 ? (Crc >> 1) ^ 0x8408 : 
                                    Crc >> 1 ;
    }

    return Crc ;
}

uint16_t crc( uint8_t* pData, uint32_t Len )
{
    uint16_t Crc = 0xffff;

    for( uint32_t i = 0; i < Len; i++ )
    {
        Crc = Utils_CRC16_MCRF4XX( Crc, pData[i] );
    }
    return (Crc);
}

int main()
{
    int8_t val1 = 30;
    int8_t val2 = 30;

    // Arbitrary Test Message
    uint8_t message[] = 
    {
        (uint8_t)54
    };

    /*
    // Sample Test Message (Actually what I intend to transmit)
    uint8_t message[] = 
    {
        (uint8_t)250,
        (uint8_t)7,
        (uint8_t)21,
        (uint8_t)2,
        (uint8_t)2,
        (uint8_t)val1,
        (uint8_t)val2
    };
    */

    //uint8_t test[] = "123456789";

    uint16_t remainder = crc(message, sizeof(message));
    // Expected DEC: 28561
    // Actual DEC: 23346

    std::cout << "CRC: " << remainder << std::endl;

    return 0;
}
Equilibrium23
  • 65
  • 1
  • 10
  • The "Actual DEC" value corresponds to the correct CRC for the string "6" (ASCII 54) ie. the "Arbitrary Test Message" (`message`), while the "Expected DEC" corresponds to the CRC for the string "123456789". – nielsen Mar 22 '21 at 19:18
  • I don't know this particular CRC but the initial `Crc ^= Byte` seems weird. Also, you have a bug returning `int16_t` when it should be `uint16_t`. – Lundin Mar 23 '21 at 10:15

1 Answers1

1

If you do this:

    uint8_t test[] = "123456789";

    uint16_t remainder = crc(test, sizeof(test)-1);

then you get the expected result, 28561.

You need to subtract 1 from sizeof(test) to exclude the terminating 0.

nielsen
  • 5,641
  • 10
  • 27
  • Hi, yes so that I am aware of, that works fine and is what I said in the question. The issue is when I am then using the message array (the uncommented one) I get a CRC of 65535, or it returns 0. I would have expected the expected value to be returned? I have applied the fix you said + the change @Lundin mentioned too. Any ideas how to correct this? – Equilibrium23 Mar 23 '21 at 15:30
  • Also, I think adding the sizeof(test) - 1 or whatever the message variable name is would then just pass 0 if the length of the array is 1? – Equilibrium23 Mar 23 '21 at 15:33
  • Yes, you should only subtract 1 from the sizeof(test) because `test` is a string and thus has an implicit terminating 0. Do not do it with `message` which is not initialized as a string. – nielsen Mar 23 '21 at 16:27