Bluetooth Low Energy for Smart Plug

Dependencies:   BLE_API mbed nRF51822

Fork of SmartPlugBLE by Pavit Noinongyao

Committer:
Slepnir
Date:
Tue Jul 14 10:10:19 2015 +0000
Revision:
4:721ae30c92f8
Parent:
3:aaa92c61931a
For debugging

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Slepnir 3:aaa92c61931a 1
Slepnir 3:aaa92c61931a 2
Slepnir 3:aaa92c61931a 3 #include "crc2.h"
Slepnir 3:aaa92c61931a 4
Slepnir 3:aaa92c61931a 5
Slepnir 3:aaa92c61931a 6 /*
Slepnir 3:aaa92c61931a 7 * Derive parameters from the standard-specific parameters in crc.h.
Slepnir 3:aaa92c61931a 8 */
Slepnir 3:aaa92c61931a 9 #define WIDTH (8 * sizeof(crc))
Slepnir 3:aaa92c61931a 10 #define TOPBIT (1 << (WIDTH - 1))
Slepnir 3:aaa92c61931a 11
Slepnir 3:aaa92c61931a 12 #if (REFLECT_DATA == TRUE)
Slepnir 3:aaa92c61931a 13 #undef REFLECT_DATA
Slepnir 3:aaa92c61931a 14 #define REFLECT_DATA(X) ((unsigned char) reflect((X), 8))
Slepnir 3:aaa92c61931a 15 #else
Slepnir 3:aaa92c61931a 16 #undef REFLECT_DATA
Slepnir 3:aaa92c61931a 17 #define REFLECT_DATA(X) (X)
Slepnir 3:aaa92c61931a 18 #endif
Slepnir 3:aaa92c61931a 19
Slepnir 3:aaa92c61931a 20 #if (REFLECT_REMAINDER == TRUE)
Slepnir 3:aaa92c61931a 21 #undef REFLECT_REMAINDER
Slepnir 3:aaa92c61931a 22 #define REFLECT_REMAINDER(X) ((crc) reflect((X), WIDTH))
Slepnir 3:aaa92c61931a 23 #else
Slepnir 3:aaa92c61931a 24 #undef REFLECT_REMAINDER
Slepnir 3:aaa92c61931a 25 #define REFLECT_REMAINDER(X) (X)
Slepnir 3:aaa92c61931a 26 #endif
Slepnir 3:aaa92c61931a 27
Slepnir 3:aaa92c61931a 28
Slepnir 3:aaa92c61931a 29 /*********************************************************************
Slepnir 3:aaa92c61931a 30 *
Slepnir 3:aaa92c61931a 31 * Function: reflect()
Slepnir 3:aaa92c61931a 32 *
Slepnir 3:aaa92c61931a 33 * Description: Reorder the bits of a binary sequence, by reflecting
Slepnir 3:aaa92c61931a 34 * them about the middle position.
Slepnir 3:aaa92c61931a 35 *
Slepnir 3:aaa92c61931a 36 * Notes: No checking is done that nBits <= 32.
Slepnir 3:aaa92c61931a 37 *
Slepnir 3:aaa92c61931a 38 * Returns: The reflection of the original data.
Slepnir 3:aaa92c61931a 39 *
Slepnir 3:aaa92c61931a 40 *********************************************************************/
Slepnir 3:aaa92c61931a 41 static unsigned long
Slepnir 3:aaa92c61931a 42 reflect(unsigned long data, unsigned char nBits)
Slepnir 3:aaa92c61931a 43 {
Slepnir 3:aaa92c61931a 44 unsigned long reflection = 0x00000000;
Slepnir 3:aaa92c61931a 45 unsigned char bit;
Slepnir 3:aaa92c61931a 46
Slepnir 3:aaa92c61931a 47 /*
Slepnir 3:aaa92c61931a 48 * Reflect the data about the center bit.
Slepnir 3:aaa92c61931a 49 */
Slepnir 3:aaa92c61931a 50 for (bit = 0; bit < nBits; ++bit)
Slepnir 3:aaa92c61931a 51 {
Slepnir 3:aaa92c61931a 52 /*
Slepnir 3:aaa92c61931a 53 * If the LSB bit is set, set the reflection of it.
Slepnir 3:aaa92c61931a 54 */
Slepnir 3:aaa92c61931a 55 if (data & 0x01)
Slepnir 3:aaa92c61931a 56 {
Slepnir 3:aaa92c61931a 57 reflection |= (1 << ((nBits - 1) - bit));
Slepnir 3:aaa92c61931a 58 }
Slepnir 3:aaa92c61931a 59
Slepnir 3:aaa92c61931a 60 data = (data >> 1);
Slepnir 3:aaa92c61931a 61 }
Slepnir 3:aaa92c61931a 62
Slepnir 3:aaa92c61931a 63 return (reflection);
Slepnir 3:aaa92c61931a 64
Slepnir 3:aaa92c61931a 65 } /* reflect() */
Slepnir 3:aaa92c61931a 66
Slepnir 3:aaa92c61931a 67
Slepnir 3:aaa92c61931a 68 /*********************************************************************
Slepnir 3:aaa92c61931a 69 *
Slepnir 3:aaa92c61931a 70 * Function: crcSlow()
Slepnir 3:aaa92c61931a 71 *
Slepnir 3:aaa92c61931a 72 * Description: Compute the CRC of a given message.
Slepnir 3:aaa92c61931a 73 *
Slepnir 3:aaa92c61931a 74 * Notes:
Slepnir 3:aaa92c61931a 75 *
Slepnir 3:aaa92c61931a 76 * Returns: The CRC of the message.
Slepnir 3:aaa92c61931a 77 *
Slepnir 3:aaa92c61931a 78 *********************************************************************/
Slepnir 3:aaa92c61931a 79 crc
Slepnir 3:aaa92c61931a 80 crcSlow(unsigned char const message[], int nBytes)
Slepnir 3:aaa92c61931a 81 {
Slepnir 3:aaa92c61931a 82 crc remainder = INITIAL_REMAINDER;
Slepnir 3:aaa92c61931a 83 int byte;
Slepnir 3:aaa92c61931a 84 unsigned char bit;
Slepnir 3:aaa92c61931a 85
Slepnir 3:aaa92c61931a 86
Slepnir 3:aaa92c61931a 87 /*
Slepnir 3:aaa92c61931a 88 * Perform modulo-2 division, a byte at a time.
Slepnir 3:aaa92c61931a 89 */
Slepnir 3:aaa92c61931a 90 for (byte = 0; byte < nBytes; ++byte)
Slepnir 3:aaa92c61931a 91 {
Slepnir 3:aaa92c61931a 92 /*
Slepnir 3:aaa92c61931a 93 * Bring the next byte into the remainder.
Slepnir 3:aaa92c61931a 94 */
Slepnir 3:aaa92c61931a 95 remainder ^= (REFLECT_DATA(message[byte]) << (WIDTH - 8));
Slepnir 3:aaa92c61931a 96
Slepnir 3:aaa92c61931a 97 /*
Slepnir 3:aaa92c61931a 98 * Perform modulo-2 division, a bit at a time.
Slepnir 3:aaa92c61931a 99 */
Slepnir 3:aaa92c61931a 100 for (bit = 8; bit > 0; --bit)
Slepnir 3:aaa92c61931a 101 {
Slepnir 3:aaa92c61931a 102 /*
Slepnir 3:aaa92c61931a 103 * Try to divide the current data bit.
Slepnir 3:aaa92c61931a 104 */
Slepnir 3:aaa92c61931a 105 if (remainder & TOPBIT)
Slepnir 3:aaa92c61931a 106 {
Slepnir 3:aaa92c61931a 107 remainder = (remainder << 1) ^ POLYNOMIAL;
Slepnir 3:aaa92c61931a 108 }
Slepnir 3:aaa92c61931a 109 else
Slepnir 3:aaa92c61931a 110 {
Slepnir 3:aaa92c61931a 111 remainder = (remainder << 1);
Slepnir 3:aaa92c61931a 112 }
Slepnir 3:aaa92c61931a 113 }
Slepnir 3:aaa92c61931a 114 }
Slepnir 3:aaa92c61931a 115
Slepnir 3:aaa92c61931a 116 /*
Slepnir 3:aaa92c61931a 117 * The final remainder is the CRC result.
Slepnir 3:aaa92c61931a 118 */
Slepnir 3:aaa92c61931a 119 return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
Slepnir 3:aaa92c61931a 120
Slepnir 3:aaa92c61931a 121 } /* crcSlow() */
Slepnir 3:aaa92c61931a 122
Slepnir 3:aaa92c61931a 123
Slepnir 3:aaa92c61931a 124 crc crcTable[256];
Slepnir 3:aaa92c61931a 125
Slepnir 3:aaa92c61931a 126
Slepnir 3:aaa92c61931a 127 /*********************************************************************
Slepnir 3:aaa92c61931a 128 *
Slepnir 3:aaa92c61931a 129 * Function: crcInit()
Slepnir 3:aaa92c61931a 130 *
Slepnir 3:aaa92c61931a 131 * Description: Populate the partial CRC lookup table.
Slepnir 3:aaa92c61931a 132 *
Slepnir 3:aaa92c61931a 133 * Notes: This function must be rerun any time the CRC standard
Slepnir 3:aaa92c61931a 134 * is changed. If desired, it can be run "offline" and
Slepnir 3:aaa92c61931a 135 * the table results stored in an embedded system's ROM.
Slepnir 3:aaa92c61931a 136 *
Slepnir 3:aaa92c61931a 137 * Returns: None defined.
Slepnir 3:aaa92c61931a 138 *
Slepnir 3:aaa92c61931a 139 *********************************************************************/
Slepnir 3:aaa92c61931a 140 void
Slepnir 3:aaa92c61931a 141 crcInit()
Slepnir 3:aaa92c61931a 142 {
Slepnir 3:aaa92c61931a 143 crc remainder;
Slepnir 3:aaa92c61931a 144 int dividend;
Slepnir 3:aaa92c61931a 145 unsigned char bit;
Slepnir 3:aaa92c61931a 146
Slepnir 3:aaa92c61931a 147
Slepnir 3:aaa92c61931a 148 /*
Slepnir 3:aaa92c61931a 149 * Compute the remainder of each possible dividend.
Slepnir 3:aaa92c61931a 150 */
Slepnir 3:aaa92c61931a 151 for (dividend = 0; dividend < 256; ++dividend)
Slepnir 3:aaa92c61931a 152 {
Slepnir 3:aaa92c61931a 153 /*
Slepnir 3:aaa92c61931a 154 * Start with the dividend followed by zeros.
Slepnir 3:aaa92c61931a 155 */
Slepnir 3:aaa92c61931a 156 remainder = dividend << (WIDTH - 8);
Slepnir 3:aaa92c61931a 157
Slepnir 3:aaa92c61931a 158 /*
Slepnir 3:aaa92c61931a 159 * Perform modulo-2 division, a bit at a time.
Slepnir 3:aaa92c61931a 160 */
Slepnir 3:aaa92c61931a 161 for (bit = 8; bit > 0; --bit)
Slepnir 3:aaa92c61931a 162 {
Slepnir 3:aaa92c61931a 163 /*
Slepnir 3:aaa92c61931a 164 * Try to divide the current data bit.
Slepnir 3:aaa92c61931a 165 */
Slepnir 3:aaa92c61931a 166 if (remainder & TOPBIT)
Slepnir 3:aaa92c61931a 167 {
Slepnir 3:aaa92c61931a 168 remainder = (remainder << 1) ^ POLYNOMIAL;
Slepnir 3:aaa92c61931a 169 }
Slepnir 3:aaa92c61931a 170 else
Slepnir 3:aaa92c61931a 171 {
Slepnir 3:aaa92c61931a 172 remainder = (remainder << 1);
Slepnir 3:aaa92c61931a 173 }
Slepnir 3:aaa92c61931a 174 }
Slepnir 3:aaa92c61931a 175
Slepnir 3:aaa92c61931a 176 /*
Slepnir 3:aaa92c61931a 177 * Store the result into the table.
Slepnir 3:aaa92c61931a 178 */
Slepnir 3:aaa92c61931a 179 crcTable[dividend] = remainder;
Slepnir 3:aaa92c61931a 180 }
Slepnir 3:aaa92c61931a 181
Slepnir 3:aaa92c61931a 182 } /* crcInit() */
Slepnir 3:aaa92c61931a 183
Slepnir 3:aaa92c61931a 184
Slepnir 3:aaa92c61931a 185 /*********************************************************************
Slepnir 3:aaa92c61931a 186 *
Slepnir 3:aaa92c61931a 187 * Function: crcFast()
Slepnir 3:aaa92c61931a 188 *
Slepnir 3:aaa92c61931a 189 * Description: Compute the CRC of a given message.
Slepnir 3:aaa92c61931a 190 *
Slepnir 3:aaa92c61931a 191 * Notes: crcInit() must be called first.
Slepnir 3:aaa92c61931a 192 *
Slepnir 3:aaa92c61931a 193 * Returns: The CRC of the message.
Slepnir 3:aaa92c61931a 194 *
Slepnir 3:aaa92c61931a 195 *********************************************************************/
Slepnir 3:aaa92c61931a 196 crc
Slepnir 3:aaa92c61931a 197 crcFast(unsigned char const message[], int nBytes)
Slepnir 3:aaa92c61931a 198 {
Slepnir 3:aaa92c61931a 199 crc remainder = INITIAL_REMAINDER;
Slepnir 3:aaa92c61931a 200 unsigned char data;
Slepnir 3:aaa92c61931a 201 int byte;
Slepnir 3:aaa92c61931a 202
Slepnir 3:aaa92c61931a 203
Slepnir 3:aaa92c61931a 204 /*
Slepnir 3:aaa92c61931a 205 * Divide the message by the polynomial, a byte at a time.
Slepnir 3:aaa92c61931a 206 */
Slepnir 3:aaa92c61931a 207 for (byte = 0; byte < nBytes; ++byte)
Slepnir 3:aaa92c61931a 208 {
Slepnir 3:aaa92c61931a 209 data = REFLECT_DATA(message[byte]) ^ (remainder >> (WIDTH - 8));
Slepnir 3:aaa92c61931a 210 remainder = crcTable[data] ^ (remainder << 8);
Slepnir 3:aaa92c61931a 211 }
Slepnir 3:aaa92c61931a 212
Slepnir 3:aaa92c61931a 213 /*
Slepnir 3:aaa92c61931a 214 * The final remainder is the CRC.
Slepnir 3:aaa92c61931a 215 */
Slepnir 3:aaa92c61931a 216 return (REFLECT_REMAINDER(remainder) ^ FINAL_XOR_VALUE);
Slepnir 3:aaa92c61931a 217
Slepnir 3:aaa92c61931a 218 } /* crcFast() */
Slepnir 3:aaa92c61931a 219