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.

Modify CRC-16 to CRC-16-DNP

Other Parts Discussed in Thread: MSP430F2618

Hi all,

I'm implementing a Wireless M-Bus protocol in MSP430F6137RF900 board and it used a specific CRC format. In my case CRC-16-DNP wich algorithm is

x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1

besides

x16 + x15 + x2 + 1 

 

How can i change it? I dont know where CRC is configurate and if its possible change it

Thanks in advance,

Victor

  • Hi all again,

    I still searching an answer in internet, but i cant find it.

    Btw, i would like to know how implemente manchester codification too. I saw in SmartRF Studio that i can enable it, but this program didnt reconiced so good my board. I mean the firmware of my EM430F6137RF900 is 2.6.4 or something similar but when i connected it to SmartRF the program want o update the firmware to 2.4.4, an old version. Some one knows any solution?

    Thanks in advance,

    Víctor

     

  • The 6137 has an internal CRC module that uses a hardwired CCITT compatible algorithm. Set the seed, push the bytes/words into the input and receive the CRC as output. Nothing to configure.

    If you want something else, then you need to implement it in software.

    My own tests with this module reveaed a 400% speed compared to an identical and highly optimized software algorithm. But then, your implementation is way more complex, so I guess you'll end up with a speed penalty of a factor of 20 or more compared to the CCITT hardware.

  • I have seen people using table lookup to update CRC-16. Something like:

    crc = (crc >> 8) ^ crctable[(crc ^ *dp++) & 0xFF];

    where crctable[256] is the only thing that is CRC generator polynomial dependent.

    I think the per byte execution tine is about 3:1 when compared with the 430 hardware CRC-16. (No matter what the generator polynomial is.)

  • old_cow_yellow said:
    I think the per byte execution tine is about 3:1 when compared with the 430 hardware CRC-16. (No matter what the generator polynomial is.)


    Hmm, looks odd. It will EOR the upper 8 bit of the last iteration to the tabel entry selected by the EORed low 8 bits of data and last iteration.
    Not to mention the 512 bytes required for the table (and the effort to create it), I don't think you can put any polynom into this kind of table.
    But I'm not math genius

  • I've been trying to implement a compatible crc module using Python script that matches the result using the hardware crc in the msp430f5xxA.  I haven't been able to

    find one.  Have you?  I've been using crcmod with all different predefined flavors with no good results.  Nothing I do whether byte or word writes, whether reversed or

    non reversed works.

  • We are dealing with a trade-off between silicon-gates, execution speed, code-size, and “effort”.
    Using table lookup is just one of the options that requires very little effort.

    Here is one way to generate the crctable[256].

    Define a 16-bit constant P to represent the generator polynomial coefficients.
    LSB first and ignore the MSB (which is always a 1).
    A few examples:
    For x16 + x15 + x2 + 1, use 0xA001 as P.
    For x16 + x12 + x5 + 1, use 0x8408 as P.
    For x16 + x15 + x11 + x9 + x8 + x7 + x5 + x4 + x2 + x + 1, use 0xEDD1 as P.
    For x16 + x13 + x12 + x11 + x10 + x8 + x6 + x5 + x2 + 1, use 0xA6BC as P.
    For x16 + x10 + x8 + x7 + x3 + 1, use 0x91A0 as P.

    #define P (????)
    main()
    {
      unsigned v;
      printf("// P = 0x%04x\n", P);
      printf("unsigned int crctable[256] =\n{\n  ");
      for (int b = 0; b < 256 ; b++)
      {
        v = b;
        for (int i = 8; i--; )
          v = v & 1 ? (v >> 1) ^ P : v >> 1;
        printf("0x%04x", v);
        if (b == 255)
          printf("\n};\n");
        else if (b % 8 == 7)
          printf("\n  ");
        else
          printf(",");
        }
    }

  • Sherine,

    I think if you define P as 0x8408 and generate the crctable[256] to work with the one-liner I cited earlier, it should match the "reverse" CRC generated by the F54xxA hardware.

    Please let me know if it does not work.

    --OCY

  • Thanks,

    i will try it this night or tomorrow. ASAP i know something ill tell you.

    Victor

  • OCY,

    Theoretically, if I take the P(0x8408) and initialize the CRC with 0xFFFF, reverse algorithm, then the crcmod should equal the MSP430f54xxxA.  It does not.  So, then I implemented your crc table and it still doesn't match.  I have not been able to match any algorithm with the MSP430 hardware.  It's very frustrating considering this CRC value must be able to be calculated outside the msp environment at some point to verify firmware integrity.  Using just two data values: 00b1 and 0010, initializing CRCINIRES = 0xFFFF, inputing the two values into CRDIRB, I get CRCRESR = 0x6b00 or CRCINIRES = 0x00d6.  There isn't an algorithm I've tried that gets this same solution. . . not even any of the online crc calculators.  Any other ideas?  

    Sherine

  • Try the online CRC calculation site for testing.

    When I got the 5438 (non-A), I thought I could replace the software implementation that gives use the CRC_CCITT (0xFFFF) by hardware. Then I found that the non-A CRC module implementes the algorithm bit-reversed.
    I tested different approaches to bit-reverse the parameters (full 256 byte table, nibble table, software) and dumped them all becausethey weren't much faster than out software solution (140 to 240%) but significantly larger. Using the reverse registers of the 5438A, 400% were possible, with smaller code too. But then we had to use the more expensive A devices (which weren't available in quantities back then). So I sticked with the software algorithm we already used on PICs and ATMegas.

    sherine johnson said:
    There isn't an algorithm I've tried that gets this same solution

    The results of the hardware CRC when stuffed with inverted bytes were exactly matching the ones of our software or the above website (0x29B1 for the string "123456789"). I didn't have an real A-type then, so I never tried.

    Maybe you should post the code you're using to get your results.

     

  • Sherine,

    The table and my one line of c code is to update the CRC with one byte of data.

    The F54xxA CRC hardware can do either 1-byte or 1-word (2 bytes) at a time. If you tell it to do 1-word, I am not sure which byte of the 2 is done first. It makes all the difference.

    Is your 00b1 one word or one byte? DId you feed that to CRCDIRB or CRCDIRB_L?

    --OCY


  • Thanks everyone for all your help... I finally got it to work...my Python script now calculates a CRC that matches the CRC hardware module...The solution was to find the crc algorithm that TI released with the Bootstrap utility.  That one line of code matches the hardware algorithm implemented.  Finally!!!  

    Happy coding!

    Sherine

  • Hi sherine,

    What location does the compiler store the CRC at?  What does it use for the starting address, ending address, and the address to store the 16-bit CRC?  If it helps, we are using an MSP430F2618, and need to have a firmware integrity test at programming time and during startup.

    Also, if you have a link to the info on the Bootstrap utility, I would appreciate it if you could post it here!

    Many thanks,

    Scott

**Attention** This is a public forum