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.

CCS/MSP430FR2422: TLV structure checksum?

Part Number: MSP430FR2422
Other Parts Discussed in Thread: MSP430FR5739

Tool/software: Code Composer Studio

Hello everybody!

I am working on an MSP430FR2422 design, and I am trying to write the little routine that verifies the TLV structure.  The datasheet says use CRC-16-CCITT, and there is some sample code for a different CPU using the built-in CRC module.  There are also a specification of how to apply the CRC-16-CCITT for this case on the internets somewhere.

None of this works.

On an odd chance I tried all permutations of the following: (1) initializing CRC accumulator with 0 or 0xFFFF, (2) loading data direct or bit-reversed, (2) swapping LS and MS bytes or not swapping, or loading data byte-wise, (3) checksumming the block up to 0x1AEF vs 0x1AFF.  I also tried (4) checksumming the block starting at 0x1AF2, (5) calculating the old-style checksum (16-bit-wise sum of all words of the structure), and (6) XOR of all words of the structure (yes, this is 50 variations total, and no, it didn't take more than two hours -- I'm quick.)

None of that worked either.

Help, please?

  -victor

  • Hi Victor,

    You can try the Peripherals Example for CRC. I would also suggest you to go through the CRC chapter of the device User's Guide for how to use the CRC module of MSP430.

  • Here is the example code that you suggested, as applied to the TLV CRC:

    uint16_t acc;

    // Software algorithm - CCITT CRC16 code
    unsigned int CCITT_Update(unsigned int init, unsigned int input)
    {
      unsigned int CCITT;
      CCITT =(unsigned char)(init >> 8)|(init << 8);
      CCITT ^= input;
      CCITT ^= (unsigned char)(CCITT & 0xFF) >> 4;
      CCITT ^= (CCITT << 8) << 4;
      CCITT ^= ((CCITT & 0xFF) << 4) << 1;
      return CCITT;
    }

    // Check TLV area of information flash
    bool tlv_check(void)
    {
      unsigned i;

      CRCINIRES = 0xffff;
      for (i = 0x01a04; i < 0x01af0; i += 2)
      {
        uint16_t a = *(uint16_t*) i;
        CRCDIRB = a;
      };

      uint16_t acc = 0xffff;
      for (i = 0x01a04; i < 0x01af0; i += 1)
        acc = CCITT_Update(acc, *(uint8_t*) i);

      while (1);
    }

    Both the software update function and the hardware CRC module calculate the same value -- on my CPU, an MSP430FR2422, this is 0x0D46. My TLV structure is this, spanning 0x1A00 through 0x1AEF:

    0x1A00: 0606 0571 8311 1010 0A08 27E2 2DF1 0018
    0x1A10: 0046 FEFC 0811 8011 0000 02C3 0348 0412
    0x1A20: 7FF9 014B FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A30: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A40: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A50: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A60: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A70: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A80: FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x1A90: 0110 965E 011A 0000 0110 96B7 0118 010E
    0x1AA0: 011A 5800 0110 96B8 0114 0010 0110 965E
    0x1AB0: 0112 0000 0110 9614 0112 0000 0116 0600
    0x1AC0: 0110 9601 011E 9000 0110 961D 0112 0040
    0x1AD0: 0116 6B64 0110 9602 0116 8CAC 0118 BB30
    0x1AE0: 0114 0C27 0154 02D2 1A90 0001 F982 3CC3

    As you can see, the CRC stored in the structure at address 0x1A02 is 0x0571.

    No matter how we compare 0x0D46 to 0x0571, byte reversed, bit reversed, or a combination, they don't match... Oops.

    What am I missing?

  • Hi Victor,

    Unfortunately I cannot provide any more answers, but I can provide the '430 team members another data point.

    Steps Taken

    I also tried repeating similar experiments on the MSP430FR5739, and came up with sadly the same results. I used the below modified code example to try a combination of data reversed, get results bits reversed, and memory ranges (0x1A04-0x1AFF, 0x1A04-0x1A7F) and cannot replicate the CRC value stored in the device's TLV area.

    #include "driverlib.h"
    
    void main (void)
    {
        uint16_t crcSeed = 0xFFFF;
        uint16_t data[] = {0x0123,
                               0x4567,
                               0x8910,
                               0x1112,
                               0x1314};
        uint16_t crcResult;
        uint16_t i;
    
        //Stop WDT
        WDT_A_hold(WDT_A_BASE);
    
        //Set P1.0 as an output
        GPIO_setAsOutputPin(
            GPIO_PORT_P1,
            GPIO_PIN0);
    
        //Set the CRC seed
        CRC_setSeed(CRC_BASE,
            crcSeed);
    
        for (i = 0x1A04; i <= 0x1AFF; i++)
        {
            //Add all of the values into the CRC signature
            CRC_set16BitDataReversed(CRC_BASE,
                *(unsigned char*)(i));
        }
    
        //Save the current CRC signature checksum to be compared for later
        crcResult = CRC_getResult(CRC_BASE);
    
    
        //Enter LPM4, interrupts enabled
        __bis_SR_register(LPM4_bits);
        __no_operation();
    }
    

    Below is the memory data itself from my particular device:

    0x001A00 0606 1F72 8103 2020 0A08 FFFF FFFF FFFF
    0x001A10 FFFF FFFF 1013 FFFF FFFF FFFF FFFF FFFF
    0x001A20 FFFF FFFF FFFF 0612 FFFF FFFF FFFF 6C02
    0x001A30 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A40 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A50 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A60 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A70 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A80 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001A90 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001AA0 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001AB0 FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF
    0x001AC0 FFFF FFFF FFFF 032A 0030 0194 FFDF 0196
    0x001AD0 0000 0110 9602 0116 E558 0118 2404 0110
    0x001AE0 961C 0118 1912 0110 96D6 0116 004A 1ACA
    0x001AF0 0000 0000 0000 3CC3 0000 8118 0214 FFFF
    Resources
    One related resource I found for the MSP430F5xx family of devices is an E2E post here, however the code example has been essentially replicated with the one I've shared above with failing results.
    Question
    '430 Team: Is the FRAM TLV structure and especially CRC value calculated/structured differently from the MSP430F5xx family of devices?
    Best Regards,
    Mark-
  • Hi Victor,

    I am testing the problem you described and will contact you later.

    Best Regards
    Johnson
  • Hi Victor,

        We have some errors in the length of the CRC check in datasheet of the MSP430FR2422, as shown in the following figure:

     

       The address described in the figure is from 0x1A04h to 0x1AEF, and the actual address should be from 0x1A04h to 0x1AF5.
       The correct verification code is as follows:

    #include <msp430.h> 
    
    unsigned int CRC_Results = 0;
    unsigned int i;
    unsigned int CRC_Memory = 0;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;       // stop watchdog timer
        PM5CTL0 &= ~LOCKLPM5;           // Disable the GPIO power-on default high-impedance mode
    
        CRCINIRES = 0xFFFF;             // Init CRC with 0xFFFF
    
        CRC_Memory = *(unsigned int*) 0x01a02;
    
        for (i = 0x01a04; i < 0x01af5; i += 2)
        {
            CRCDIRB = *(unsigned int*) i;
         };
    
        CRC_Results = CRCINIRES;
        return 0;
    }
    



       I have tested the code, The result is correct, thank you for your feedback on this issue, we will update datasheet in future versions.

    Thanks & Best Regards

    Johnson

**Attention** This is a public forum