disputedip.com

Tag: c30

CRC With dsPIC

by Martyn on Mar.23, 2009, under News

CRC’s are probably the most time consuming thing you can do in a data stream, but they have their uses - and not just for checking that data is correct, but more on that in a later post.

I found that the microchip documentation extremely useful, and I suspect you will to: Section 36 PCRC. But the biggest shout out should go to billysdomain in the Microchip Forums who actually got it working, the bits which make it work are his code, lets begin:

  1.  
  2. int CalculateCRC(DataPL *DataPacket)
  3. {
  4.      unsigned int j, length = (DATAPL_LEN*2)-2;
  5.      unsigned char *ptr, *data;
  6.      ptr = (unsigned char *)&CRCDAT;
  7.  
  8.      CRCCON = 0×0F;      // Configure the polynomial length (PLEN)
  9.      _CRCIF = 0;         // Clear the CRC flag
  10.      _CRCIE = 1;         // Enable the int
  11.  
  12.      CRCXOR = 0×1021;    // Polynomial - crc-16
  13.      CRCWDAT = 0×0000;   // Initialize CRCWDAT with 0
  14.  
  15.      data = (*DataPacket).CHARS;
  16.  
  17.      length >>= 1;
  18.      for(j = 0; j < length; j++)
  19.      {
  20.           //Must use pairs of bytes to get the correct result
  21.           *ptr = *data++;  //write data into FIFO
  22.           *ptr = *data++;  //write data into FIFO
  23.  
  24.           if (CRCCONbits.CRCFUL)  //check if FIFO is full
  25.           {
  26.                CRCCONbits.CRCGO = 1;         //start CRC engine
  27.                while (!CRCCONbits.CRCMPT);   //check if FIFO is empty
  28.                CRCCONbits.CRCGO = 0;         //stop CRC engine
  29.           }
  30.      }
  31.  
  32.      CRCDAT = 0×0000;
  33.      CRCCONbits.CRCGO = 1// (Re)Start the calculation
  34.  
  35.      comms_datapacket = DataPacket; // Save a reference
  36.      // With a bit of luck CRC finishes before we send
  37.      // the data via SPI…
  38.  
  39.      return 1;
  40. }
  41.  
  42. //Use the software CRC calculator
  43. static const unsigned int CRC16Table[256] = {
  44. 0×0000,0×1021,0×2042,0×3063,0×4084,0×50a5,0×60c6,0×70e7,
  45. 0×8108,0×9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
  46. 0×1231,0×0210,0×3273,0×2252,0×52b5,0×4294,0×72f7,0×62d6,
  47. 0×9339,0×8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
  48. 0×2462,0×3443,0×0420,0×1401,0×64e6,0×74c7,0×44a4,0×5485,
  49. 0xa56a,0xb54b,0×8528,0×9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
  50. 0×3653,0×2672,0×1611,0×0630,0×76d7,0×66f6,0×5695,0×46b4,
  51. 0xb75b,0xa77a,0×9719,0×8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
  52. 0×48c4,0×58e5,0×6886,0×78a7,0×0840,0×1861,0×2802,0×3823,
  53. 0xc9cc,0xd9ed,0xe98e,0xf9af,0×8948,0×9969,0xa90a,0xb92b,
  54. 0×5af5,0×4ad4,0×7ab7,0×6a96,0×1a71,0×0a50,0×3a33,0×2a12,
  55. 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0×9b79,0×8b58,0xbb3b,0xab1a,
  56. 0×6ca6,0×7c87,0×4ce4,0×5cc5,0×2c22,0×3c03,0×0c60,0×1c41,
  57. 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0×8d68,0×9d49,
  58. 0×7e97,0×6eb6,0×5ed5,0×4ef4,0×3e13,0×2e32,0×1e51,0×0e70,
  59. 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0×9f59,0×8f78,
  60. 0×9188,0×81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
  61. 0×1080,0×00a1,0×30c2,0×20e3,0×5004,0×4025,0×7046,0×6067,
  62. 0×83b9,0×9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
  63. 0×02b1,0×1290,0×22f3,0×32d2,0×4235,0×5214,0×6277,0×7256,
  64. 0xb5ea,0xa5cb,0×95a8,0×8589,0xf56e,0xe54f,0xd52c,0xc50d,
  65. 0×34e2,0×24c3,0×14a0,0×0481,0×7466,0×6447,0×5424,0×4405,
  66. 0xa7db,0xb7fa,0×8799,0×97b8,0xe75f,0xf77e,0xc71d,0xd73c,
  67. 0×26d3,0×36f2,0×0691,0×16b0,0×6657,0×7676,0×4615,0×5634,
  68. 0xd94c,0xc96d,0xf90e,0xe92f,0×99c8,0×89e9,0xb98a,0xa9ab,
  69. 0×5844,0×4865,0×7806,0×6827,0×18c0,0×08e1,0×3882,0×28a3,
  70. 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0×8bf9,0×9bd8,0xabbb,0xbb9a,
  71. 0×4a75,0×5a54,0×6a37,0×7a16,0×0af1,0×1ad0,0×2ab3,0×3a92,
  72. 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0×9de8,0×8dc9,
  73. 0×7c26,0×6c07,0×5c64,0×4c45,0×3ca2,0×2c83,0×1ce0,0×0cc1,
  74. 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0×8fd9,0×9ff8,
  75. 0×6e17,0×7e36,0×4e55,0×5e74,0×2e93,0×3eb2,0×0ed1,0×1ef0
  76. };
  77.  
  78. unsigned int ChecksumCalcS(unsigned char *data, unsigned int len)
  79. {
  80.      unsigned int crc = 0;
  81.      unsigned int i;
  82.      for(i = 0; i < len; i++)
  83.      {
  84.           crc = (crc << 8) ^ CRC16Table[((crc >> 8) ^ *data++)];
  85.      }
  86.      return crc;
  87. }
  88.  
  89. void __attribute__((__interrupt__)) _NOPSV _CRCInterrupt(void)
  90. {
  91.      unsigned short hardware, software;
  92.  
  93.      _CRCIF = 0;       // Clear the interrupt
  94.  
  95.      while(!CRCCONbits.CRCMPT);    // Wait for CRC shifter to clear FIFO
  96.      (*comms_datapacket).CRC = CRCWDAT;
  97.  
  98.      hardware = CRCWDAT;
  99.      software = ChecksumCalcS((*comms_datapacket).CHARS,
  100.                                                                (DATAPL_LEN*2)-2);
  101.  
  102.      CRCWDAT = 0;
  103. }
  104.  

Ok, a lot of things to note ;)

  • This code will not work on its own
  • Putting a breakpoint on the last line of code will allow a software / hardware comparison
  • _NOPSV is a macro (google it)
  • The DataPL datatype is a union of an int array, char array and a large bitfield which allows me to have loads of small (or large) data types of non-standard size.
  • The interrupt is not required if working with more than 8 bytes of data as you need to wait for the buffer to clear before filling it - so might as well wait for it all to happen
  • This uses 8-bit data rather than 16-bit data, if you have a working example of this with a software table based alternative please email me! the table means I can calculate the CRC in C#
  • Most of code is by billysdomain - I was 80% there, missing 2 lines in my implementation, should have rtfm (more)

Anyhow, hope this helps someone. I might do a quick post on using CRC for synchronising serial streams soon, guess how that’s done :p

Leave a Comment :, , , , more...

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Visit our friends!

A few highly recommended friends...