I'm working on an MSP430FR5869 MCU on a device that downloads software updates and checks if the CRC matches the one created from the server, who uses a python script. I want to use the MSP430's hardware-generated CRC16, but I can't seem to get one that matches the CRC16 I get from my Python 2.7 script.

In the MCU user guide it says that a CRC16 can be made with the polynomial:

f(x) = x^16 + x^12 + x^5 + 1

It goes on to explain that first I have to send seed to initialize the result register, put in the data two bytes at the time (since it has 2 bytes allocated for data input) and then finally run the result function. I've generally used functions from a standard library provided by the MCU producers (TI). In desperation I've tried all combinations of the functions, to see if I get a matching number (reversing input, reversing result, appending with 0's, not appending with 0's), but with no success. I'm wondering if I'm forgetting something important, as this is the first time I'm working with CRC16. I'm also wondering if something is different from the Python code to the way the CRC is created on the MCU. I even tried another Python module (binascii), when I couldn't get a matching pair of CRCs, because I suspected that the Python module may have been flawed. To my surprise, I got the same CRC16 with both Python modules.

The Python code looks like this:

import crcmod

def otherTry():

    myFile = open(r"C:\Users\mabr\Desktop\TEST\files\04-3001-00-0000-0001.bin","r")
    s = myFile.read()
    crc16_func = crcmod.mkCrcFun(poly = 0x11021, initCrc = 0x0000, xorOut = 0x0000)
    print crc16_func(s)

The C++ code on the MCU is a bit more complex, as I get the data for the CRC in chunks of 128 bytes at a time. It looks like this:

      bool finished = false;
      bool lastRun = false;
      crc16drv crc;
      const uint16_t seed = 0;
      crc.init(seed);
      uint16_t tempStorage;
      uint16_t* dataPtr;
      uint8_t size = 128;
      uint16_t offset = 0;
      while(!finished)
      {
        if(fileSize - offset<128)
        {
          size = fileSize-offset;
          lastRun = true;
        }

        if (twi.transfer(&transfer) && (transfer.result == TwiMaster::kResOk))
        {
          uint8_t i;
          dataPtr = (uint16_t*) wordHolder.data;
          for(i=0;i<size/2;i++) //crc16 generation loop
          {
            crc.inputData(dataPtr);
            dataPtr++;
          }
        }
        if(offset < fileSize-128)
        {
          offset = offset+128;
        }
        else
        {
          if(lastRun)
          {
            finished = true;
          }
        }
      }
      uint16_t result = crc.getCrc();

And lastly the .cpp file with the crc-functions in it:

uint16_t baseAddress = 0x0150;

void crc16drv::init(uint16_t seed)
{
  CRC_setSeed(baseAddress, seed);
}

void crc16drv::inputData(uint16_t* dataPtr)
{
  CRC_set16BitData(baseAddress, *dataPtr);  
}

uint16_t crc16drv::getCrc()
{
  uint16_t result = CRC_getResult(baseAddress);
  return result;
}

I expected to get matching CRCs, but no matter which way I turn the input data or the result, I can't seem to match the CRC from the Python script.

0 Answers