Bluetooth Low Energy for Smart Plug

Dependencies:   BLE_API mbed nRF51822

Fork of SmartPlugBLE by Pavit Noinongyao

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers crc2.cpp Source File

crc2.cpp

00001 
00002  
00003 #include "crc2.h"
00004 
00005 
00006 /*
00007  * Derive parameters from the standard-specific parameters in crc.h.
00008  */
00009 #define WIDTH    (8 * sizeof(crc))
00010 #define TOPBIT   (1 << (WIDTH - 1))
00011 
00012 #if (REFLECT_DATA == TRUE)
00013 #undef  REFLECT_DATA
00014 #define REFLECT_DATA(X)         ((unsigned char) reflect((X), 8))
00015 #else
00016 #undef  REFLECT_DATA
00017 #define REFLECT_DATA(X)         (X)
00018 #endif
00019 
00020 #if (REFLECT_REMAINDER == TRUE)
00021 #undef  REFLECT_REMAINDER
00022 #define REFLECT_REMAINDER(X)    ((crc) reflect((X), WIDTH))
00023 #else
00024 #undef  REFLECT_REMAINDER
00025 #define REFLECT_REMAINDER(X)    (X)
00026 #endif
00027 
00028 
00029 /*********************************************************************
00030  *
00031  * Function:    reflect()
00032  * 
00033  * Description: Reorder the bits of a binary sequence, by reflecting
00034  *              them about the middle position.
00035  *
00036  * Notes:       No checking is done that nBits <= 32.
00037  *
00038  * Returns:     The reflection of the original data.
00039  *
00040  *********************************************************************/
00041 static unsigned long
00042 reflect(unsigned long data, unsigned char nBits)
00043 {
00044     unsigned long  reflection = 0x00000000;
00045     unsigned char  bit;
00046 
00047     /*
00048      * Reflect the data about the center bit.
00049      */
00050     for (bit = 0; bit < nBits; ++bit)
00051     {
00052         /*
00053          * If the LSB bit is set, set the reflection of it.
00054          */
00055         if (data & 0x01)
00056         {
00057             reflection |= (1 << ((nBits - 1) - bit));
00058         }
00059 
00060         data = (data >> 1);
00061     }
00062 
00063     return (reflection);
00064 
00065 }   /* reflect() */
00066 
00067 
00068 /*********************************************************************
00069  *
00070  * Function:    crcSlow()
00071  * 
00072  * Description: Compute the CRC of a given message.
00073  *
00074  * Notes:       
00075  *
00076  * Returns:     The CRC of the message.
00077  *
00078  *********************************************************************/
00079 crc
00080 crcSlow(unsigned char const message[], int nBytes)
00081 {
00082     crc            remainder = INITIAL_REMAINDER;
00083     int            byte;
00084     unsigned char  bit;
00085 
00086 
00087     /*
00088      * Perform modulo-2 division, a byte at a time.
00089      */
00090     for (byte = 0; byte < nBytes; ++byte)
00091     {
00092         /*
00093          * Bring the next byte into the remainder.
00094          */
00095         remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
00096 
00097         /*
00098          * Perform modulo-2 division, a bit at a time.
00099          */
00100         for (bit = 8; bit > 0; --bit)
00101         {
00102             /*
00103              * Try to divide the current data bit.
00104              */
00105             if (remainder & TOPBIT)
00106             {
00107                 remainder = (remainder << 1) ^ POLYNOMIAL;
00108             }
00109             else
00110             {
00111                 remainder = (remainder << 1);
00112             }
00113         }
00114     }
00115 
00116     /*
00117      * The final remainder is the CRC result.
00118      */
00119     return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
00120 
00121 }   /* crcSlow() */
00122 
00123 
00124 crc  crcTable[256];
00125 
00126 
00127 /*********************************************************************
00128  *
00129  * Function:    crcInit()
00130  * 
00131  * Description: Populate the partial CRC lookup table.
00132  *
00133  * Notes:       This function must be rerun any time the CRC standard
00134  *              is changed.  If desired, it can be run "offline" and
00135  *              the table results stored in an embedded system's ROM.
00136  *
00137  * Returns:     None defined.
00138  *
00139  *********************************************************************/
00140 void
00141 crcInit()
00142 {
00143     crc            remainder;
00144     int            dividend;
00145     unsigned char  bit;
00146 
00147 
00148     /*
00149      * Compute the remainder of each possible dividend.
00150      */
00151     for (dividend = 0; dividend < 256; ++dividend)
00152     {
00153         /*
00154          * Start with the dividend followed by zeros.
00155          */
00156         remainder = dividend << (WIDTH - 8);
00157 
00158         /*
00159          * Perform modulo-2 division, a bit at a time.
00160          */
00161         for (bit = 8; bit > 0; --bit)
00162         {
00163             /*
00164              * Try to divide the current data bit.
00165              */         
00166             if (remainder & TOPBIT)
00167             {
00168                 remainder = (remainder << 1) ^ POLYNOMIAL;
00169             }
00170             else
00171             {
00172                 remainder = (remainder << 1);
00173             }
00174         }
00175 
00176         /*
00177          * Store the result into the table.
00178          */
00179         crcTable[dividend] = remainder;
00180     }
00181 
00182 }   /* crcInit() */
00183 
00184 
00185 /*********************************************************************
00186  *
00187  * Function:    crcFast()
00188  * 
00189  * Description: Compute the CRC of a given message.
00190  *
00191  * Notes:       crcInit() must be called first.
00192  *
00193  * Returns:     The CRC of the message.
00194  *
00195  *********************************************************************/
00196 crc
00197 crcFast(unsigned char const message[], int nBytes)
00198 {
00199     crc            remainder = INITIAL_REMAINDER;
00200     unsigned char  data;
00201     int            byte;
00202 
00203 
00204     /*
00205      * Divide the message by the polynomial, a byte at a time.
00206      */
00207     for (byte = 0; byte < nBytes; ++byte)
00208     {
00209         data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
00210         remainder = crcTable[data] ^ (remainder << 8);
00211     }
00212 
00213     /*
00214      * The final remainder is the CRC.
00215      */
00216     return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
00217 
00218 }   /* crcFast() */
00219