• Not Answered

Modify CRC-16 to CRC-16-DNP

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


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,


13 Replies

  • 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,



  • In reply to Victor Ramirez:

    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.

  • In reply to Jens-Michael Gross:

    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.)

  • In reply to old_cow_yellow:

    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

  • In reply to Jens-Michael Gross:

    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.

  • In reply to Jens-Michael Gross:

    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 (????)
      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)
        else if (b % 8 == 7)
          printf("\n  ");

  • In reply to sherine johnson:


    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.


  • In reply to old_cow_yellow:


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


  • In reply to old_cow_yellow:


    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?  


  • In reply to sherine johnson:

    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
    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.