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.

TMS320F28377D: 32-bit Fletcher Checksum in UID_REGS

Part Number: TMS320F28377D

Hello all,

I am reading the UID_REGS from CPU1 in a TMS320F28377D and the data I get is:

0xF812BFAC,0xA22B53BD,0xAE14429C,0x32DAB547,0x43D9B0A0,0xF3659489,0x000C0E3C,0xD3D5112D

and, as the manual says, the last data (0xD3D5112D) is called UID_CHECKSUM and is the 32-bit fletcher checksum of the previous data.

When I try to calculate it myself, the result I get is 0x8011112D instead of 0xD3D5112D. The algorithm I use is this one:

uint32_t fletcher32( uint16_t const *data, size_t words )
{
 uint32_t sum1 = 0xffff, sum2 = 0xffff;

 while (words)
 {
  unsigned tlen = words > 359 ? 359 : words;
  words -= tlen;
  do {
    sum2 += sum1 += *data++;

  } while (--tlen);

  sum1 = (sum1 & 0xffff) + (sum1 >> 16);
  sum2 = (sum2 & 0xffff) + (sum2 >> 16);
 } /* Second reduction step to reduce sums to 16 bits */

 sum1 = (sum1 & 0xffff) + (sum1 >> 16);
 sum2 = (sum2 & 0xffff) + (sum2 >> 16);

 return sum2 << 16 | sum1;

}

I have also testet other versions of the 32-bit fletcher Checksum algorithms but the result is the same. Could anybody tell what it is wrong?

Many thanks in advance,

Andreu

  • Hi Andreu,

    The addressing mode where the checksum is calculated for the UID is in little endian. The MSB is read first followed by the LSB . I get the same checksum you have (0x8011112D) if I do not use little endian mode. Here is the code I tested it with:

    //seed = 0xFFFFFFFF;
    uint32_t fletch32(uint16_t const * pu16Data, uint32_t length, uint32_t seed)
    {
    uint32_t u32Sum1 = 0xFFFFU & seed, u32Sum2 = 0xFFFFU & (seed >> 16U);
    uint16_t u32Index, idx;
    uint16_t data;

    for(u32Index=0U;u32Index < length; u32Index++)
    {
    idx = u32Index^1; // little endian mode otherwise use u32Index only
    data = pu16Data[idx];
    u32Sum1 += data;
    u32Sum1 = (u32Sum1 >> 16U) + (u32Sum1 & 0xFFFFU);
    u32Sum2 += u32Sum1;
    u32Sum2 = (u32Sum2 >> 16U) + (u32Sum2 & 0xFFFFU);
    }
    return ( (u32Sum2 << 16U) | u32Sum1);
    }

    Try reading the MSB word first followed by LSB then you should get the checksum of 0xD3D5112D for the UID values above.

    Regards,
    Joseph
  • Hi Joseph,

    You are right: Now it works for me too. Many thanks for your help!

    Regards,

    Andreu