EE445M RTOS
Taken at the University of Texas Spring 2015
sw_crc.c
Go to the documentation of this file.
1 //*****************************************************************************
2 //
3 // sw_crc.c - Software CRC functions.
4 //
5 // Copyright (c) 2010-2014 Texas Instruments Incorporated. All rights reserved.
6 // Software License Agreement
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions
10 // are met:
11 //
12 // Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright
16 // notice, this list of conditions and the following disclaimer in the
17 // documentation and/or other materials provided with the
18 // distribution.
19 //
20 // Neither the name of Texas Instruments Incorporated nor the names of
21 // its contributors may be used to endorse or promote products derived
22 // from this software without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 //
36 // This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
44 //
45 //*****************************************************************************
46 
47 #include <stdint.h>
48 #include "driverlib/sw_crc.h"
49 
50 //*****************************************************************************
51 //
52 // The CRC table for the polynomial C(x) = x^8 + x^2 + x + 1 (CRC-8-CCITT).
53 //
54 //*****************************************************************************
55 static const uint8_t g_pui8Crc8CCITT[256] =
56 {
57  0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
58  0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
59  0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
60  0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
61  0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
62  0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
63  0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
64  0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
65  0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
66  0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
67  0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
68  0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
69  0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
70  0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
71  0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
72  0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
73  0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
74  0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
75  0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
76  0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
77  0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
78  0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
79  0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
80  0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
81  0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
82  0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
83  0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
84  0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
85  0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
86  0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
87  0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
88  0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
89 };
90 
91 //*****************************************************************************
92 //
93 // The CRC-16 table for the polynomial C(x) = x^16 + x^15 + x^2 + 1 (standard
94 // CRC-16, also known as CRC-16-IBM and CRC-16-ANSI).
95 //
96 //*****************************************************************************
97 static const uint16_t g_pui16Crc16[256] =
98 {
99  0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
100  0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
101  0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
102  0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
103  0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
104  0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
105  0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
106  0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
107  0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
108  0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
109  0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
110  0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
111  0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
112  0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
113  0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
114  0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
115  0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
116  0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
117  0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
118  0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
119  0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
120  0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
121  0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
122  0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
123  0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
124  0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
125  0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
126  0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
127  0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
128  0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
129  0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
130  0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
131 };
132 
133 //*****************************************************************************
134 //
135 // The CRC-32 table for the polynomial C(x) = x^32 + x^26 + x^23 + x^22 +
136 // x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1 (standard
137 // CRC32 as used in Ethernet, MPEG-2, PNG, etc.).
138 //
139 //*****************************************************************************
140 static const uint32_t g_pui32Crc32[] =
141 {
142  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
143  0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
144  0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
145  0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
146  0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
147  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
148  0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
149  0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
150  0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
151  0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
152  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
153  0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
154  0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
155  0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
156  0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
157  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
158  0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
159  0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
160  0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
161  0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
162  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
163  0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
164  0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
165  0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
166  0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
167  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
168  0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
169  0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
170  0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
171  0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
172  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
173  0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
174  0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
175  0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
176  0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
177  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
178  0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
179  0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
180  0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
181  0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
182  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
183  0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
184  0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
185  0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
186  0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
187  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
188  0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
189  0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
190  0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
191  0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
192  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
193  0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
194  0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
195  0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
196  0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
197  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
198  0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
199  0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
200  0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
201  0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
202  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
203  0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
204  0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
205  0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
206 };
207 
208 //*****************************************************************************
209 //
210 // This macro executes one iteration of the CRC-8-CCITT.
211 //
212 //*****************************************************************************
213 #define CRC8_ITER(crc, data) g_pui8Crc8CCITT[(uint8_t)((crc) ^ (data))]
214 
215 //*****************************************************************************
216 //
217 // This macro executes one iteration of the CRC-16.
218 //
219 //*****************************************************************************
220 #define CRC16_ITER(crc, data) (((crc) >> 8) ^ \
221  g_pui16Crc16[(uint8_t)((crc) ^ (data))])
222 
223 //*****************************************************************************
224 //
225 // This macro executes one iteration of the CRC-32.
226 //
227 //*****************************************************************************
228 #define CRC32_ITER(crc, data) (((crc) >> 8) ^ \
229  g_pui32Crc32[(uint8_t)((crc & 0xFF) ^ \
230  (data))])
231 
232 //*****************************************************************************
233 //
263 //
264 //*****************************************************************************
265 uint8_t
266 Crc8CCITT(uint8_t ui8Crc, const uint8_t *pui8Data, uint32_t ui32Count)
267 {
268  uint32_t ui32Temp;
269 
270  //
271  // If the data buffer is not 16 bit-aligned, then perform a single step of
272  // the CRC to make it 16 bit-aligned.
273  //
274  if((uint32_t)pui8Data & 1)
275  {
276  //
277  // Perform the CRC on this input byte.
278  //
279  ui8Crc = CRC8_ITER(ui8Crc, *pui8Data);
280 
281  //
282  // Skip this input byte.
283  //
284  pui8Data++;
285  ui32Count--;
286  }
287 
288  //
289  // If the data buffer is not word-aligned and there are at least two bytes
290  // of data left, then perform two steps of the CRC to make it word-aligned.
291  //
292  if(((uint32_t)pui8Data & 2) && (ui32Count > 1))
293  {
294  //
295  // Read the next 16 bits.
296  //
297  ui32Temp = *(uint16_t *)pui8Data;
298 
299  //
300  // Perform the CRC on these two bytes.
301  //
302  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp);
303  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp >> 8);
304 
305  //
306  // Skip these input bytes.
307  //
308  pui8Data += 2;
309  ui32Count -= 2;
310  }
311 
312  //
313  // While there is at least a word remaining in the data buffer, perform
314  // four steps of the CRC to consume a word.
315  //
316  while(ui32Count > 3)
317  {
318  //
319  // Read the next word.
320  //
321  ui32Temp = *(uint32_t *)pui8Data;
322 
323  //
324  // Perform the CRC on these four bytes.
325  //
326  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp);
327  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp >> 8);
328  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp >> 16);
329  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp >> 24);
330 
331  //
332  // Skip these input bytes.
333  //
334  pui8Data += 4;
335  ui32Count -= 4;
336  }
337 
338  //
339  // If there are 16 bits left in the input buffer, then perform two steps of
340  // the CRC.
341  //
342  if(ui32Count > 1)
343  {
344  //
345  // Read the 16 bits.
346  //
347  ui32Temp = *(uint16_t *)pui8Data;
348 
349  //
350  // Perform the CRC on these two bytes.
351  //
352  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp);
353  ui8Crc = CRC8_ITER(ui8Crc, ui32Temp >> 8);
354 
355  //
356  // Skip these input bytes.
357  //
358  pui8Data += 2;
359  ui32Count -= 2;
360  }
361 
362  //
363  // If there is a final byte remaining in the input buffer, then perform a
364  // single step of the CRC.
365  //
366  if(ui32Count != 0)
367  {
368  ui8Crc = CRC8_ITER(ui8Crc, *pui8Data);
369  }
370 
371  //
372  // Return the resulting CRC-8-CCITT value.
373  //
374  return(ui8Crc);
375 }
376 
377 //*****************************************************************************
378 //
408 //
409 //*****************************************************************************
410 uint16_t
411 Crc16(uint16_t ui16Crc, const uint8_t *pui8Data, uint32_t ui32Count)
412 {
413  uint32_t ui32Temp;
414 
415  //
416  // If the data buffer is not 16 bit-aligned, then perform a single step of
417  // the CRC to make it 16 bit-aligned.
418  //
419  if((uint32_t)pui8Data & 1)
420  {
421  //
422  // Perform the CRC on this input byte.
423  //
424  ui16Crc = CRC16_ITER(ui16Crc, *pui8Data);
425 
426  //
427  // Skip this input byte.
428  //
429  pui8Data++;
430  ui32Count--;
431  }
432 
433  //
434  // If the data buffer is not word-aligned and there are at least two bytes
435  // of data left, then perform two steps of the CRC to make it word-aligned.
436  //
437  if(((uint32_t)pui8Data & 2) && (ui32Count > 1))
438  {
439  //
440  // Read the next 16 bits.
441  //
442  ui32Temp = *(uint16_t *)pui8Data;
443 
444  //
445  // Perform the CRC on these two bytes.
446  //
447  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp);
448  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 8);
449 
450  //
451  // Skip these input bytes.
452  //
453  pui8Data += 2;
454  ui32Count -= 2;
455  }
456 
457  //
458  // While there is at least a word remaining in the data buffer, perform
459  // four steps of the CRC to consume a word.
460  //
461  while(ui32Count > 3)
462  {
463  //
464  // Read the next word.
465  //
466  ui32Temp = *(uint32_t *)pui8Data;
467 
468  //
469  // Perform the CRC on these four bytes.
470  //
471  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp);
472  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 8);
473  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 16);
474  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 24);
475 
476  //
477  // Skip these input bytes.
478  //
479  pui8Data += 4;
480  ui32Count -= 4;
481  }
482 
483  //
484  // If there are two bytes left in the input buffer, then perform two steps
485  // of the CRC.
486  //
487  if(ui32Count > 1)
488  {
489  //
490  // Read the two bytes.
491  //
492  ui32Temp = *(uint16_t *)pui8Data;
493 
494  //
495  // Perform the CRC on these two bytes.
496  //
497  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp);
498  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 8);
499 
500  //
501  // Skip these input bytes.
502  //
503  pui8Data += 2;
504  ui32Count -= 2;
505  }
506 
507  //
508  // If there is a final byte remaining in the input buffer, then perform a
509  // single step of the CRC.
510  //
511  if(ui32Count != 0)
512  {
513  ui16Crc = CRC16_ITER(ui16Crc, *pui8Data);
514  }
515 
516  //
517  // Return the resulting CRC-16 value.
518  //
519  return(ui16Crc);
520 }
521 
522 //*****************************************************************************
523 //
534 //
535 //*****************************************************************************
536 uint16_t
537 Crc16Array(uint32_t ui32WordLen, const uint32_t *pui32Data)
538 {
539  //
540  // Calculate and return the CRC-16 of this array of words.
541  //
542  return(Crc16(0, (const uint8_t *)pui32Data, ui32WordLen * 4));
543 }
544 
545 //*****************************************************************************
546 //
562 //
563 //*****************************************************************************
564 void
565 Crc16Array3(uint32_t ui32WordLen, const uint32_t *pui32Data,
566  uint16_t *pui16Crc3)
567 {
568  uint16_t ui16Crc, ui16Cri8Odd, ui16Cri8Even;
569  uint32_t ui32Temp;
570 
571  //
572  // Initialize the CRC values to zero.
573  //
574  ui16Crc = 0;
575  ui16Cri8Odd = 0;
576  ui16Cri8Even = 0;
577 
578  //
579  // Loop while there are more words in the data buffer.
580  //
581  while(ui32WordLen--)
582  {
583  //
584  // Read the next word.
585  //
586  ui32Temp = *pui32Data++;
587 
588  //
589  // Perform the first CRC on all four data bytes.
590  //
591  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp);
592  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 8);
593  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 16);
594  ui16Crc = CRC16_ITER(ui16Crc, ui32Temp >> 24);
595 
596  //
597  // Perform the second CRC on only the even-index data bytes.
598  //
599  ui16Cri8Even = CRC16_ITER(ui16Cri8Even, ui32Temp);
600  ui16Cri8Even = CRC16_ITER(ui16Cri8Even, ui32Temp >> 16);
601 
602  //
603  // Perform the third CRC on only the odd-index data bytes.
604  //
605  ui16Cri8Odd = CRC16_ITER(ui16Cri8Odd, ui32Temp >> 8);
606  ui16Cri8Odd = CRC16_ITER(ui16Cri8Odd, ui32Temp >> 24);
607  }
608 
609  //
610  // Return the resulting CRC-16 values.
611  //
612  pui16Crc3[0] = ui16Crc;
613  pui16Crc3[1] = ui16Cri8Even;
614  pui16Crc3[2] = ui16Cri8Odd;
615 }
616 
617 //*****************************************************************************
618 //
651 //
652 //*****************************************************************************
653 uint32_t
654 Crc32(uint32_t ui32Crc, const uint8_t *pui8Data, uint32_t ui32Count)
655 {
656  uint32_t ui32Temp;
657 
658  //
659  // If the data buffer is not 16 bit-aligned, then perform a single step
660  // of the CRC to make it 16 bit-aligned.
661  //
662  if((uint32_t)pui8Data & 1)
663  {
664  //
665  // Perform the CRC on this input byte.
666  //
667  ui32Crc = CRC32_ITER(ui32Crc, *pui8Data);
668 
669  //
670  // Skip this input byte.
671  //
672  pui8Data++;
673  ui32Count--;
674  }
675 
676  //
677  // If the data buffer is not word-aligned and there are at least two bytes
678  // of data left, then perform two steps of the CRC to make it word-aligned.
679  //
680  if(((uint32_t)pui8Data & 2) && (ui32Count > 1))
681  {
682  //
683  // Read the next int16_t.
684  //
685  ui32Temp = *(uint16_t *)pui8Data;
686 
687  //
688  // Perform the CRC on these two bytes.
689  //
690  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp);
691  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp >> 8);
692 
693  //
694  // Skip these input bytes.
695  //
696  pui8Data += 2;
697  ui32Count -= 2;
698  }
699 
700  //
701  // While there is at least a word remaining in the data buffer, perform
702  // four steps of the CRC to consume a word.
703  //
704  while(ui32Count > 3)
705  {
706  //
707  // Read the next word.
708  //
709  ui32Temp = *(uint32_t *)pui8Data;
710 
711  //
712  // Perform the CRC on these four bytes.
713  //
714  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp);
715  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp >> 8);
716  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp >> 16);
717  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp >> 24);
718 
719  //
720  // Skip these input bytes.
721  //
722  pui8Data += 4;
723  ui32Count -= 4;
724  }
725 
726  //
727  // If there are 16 bits left in the input buffer, then perform two steps of
728  // the CRC.
729  //
730  if(ui32Count > 1)
731  {
732  //
733  // Read the two bytes.
734  //
735  ui32Temp = *(uint16_t *)pui8Data;
736 
737  //
738  // Perform the CRC on these two bytes.
739  //
740  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp);
741  ui32Crc = CRC32_ITER(ui32Crc, ui32Temp >> 8);
742 
743  //
744  // Skip these input bytes.
745  //
746  pui8Data += 2;
747  ui32Count -= 2;
748  }
749 
750  //
751  // If there is a final byte remaining in the input buffer, then perform a
752  // single step of the CRC.
753  //
754  if(ui32Count != 0)
755  {
756  ui32Crc = CRC32_ITER(ui32Crc, *pui8Data);
757  }
758 
759  //
760  // Return the resulting CRC-32 value.
761  //
762  return(ui32Crc);
763 }
764 
765 //*****************************************************************************
766 //
767 // Close the Doxygen group.
769 //
770 //*****************************************************************************
static const uint16_t g_pui16Crc16[256]
Definition: sw_crc.c:97
static const uint8_t g_pui8Crc8CCITT[256]
Definition: sw_crc.c:55
#define CRC32_ITER(crc, data)
Definition: sw_crc.c:228
#define CRC16_ITER(crc, data)
Definition: sw_crc.c:220
uint32_t Crc32(uint32_t ui32Crc, const uint8_t *pui8Data, uint32_t ui32Count)
Definition: sw_crc.c:654
#define CRC8_ITER(crc, data)
Definition: sw_crc.c:213
uint8_t Crc8CCITT(uint8_t ui8Crc, const uint8_t *pui8Data, uint32_t ui32Count)
Definition: sw_crc.c:266
uint16_t Crc16(uint16_t ui16Crc, const uint8_t *pui8Data, uint32_t ui32Count)
Definition: sw_crc.c:411
static const uint32_t g_pui32Crc32[]
Definition: sw_crc.c:140
void Crc16Array3(uint32_t ui32WordLen, const uint32_t *pui32Data, uint16_t *pui16Crc3)
Definition: sw_crc.c:565
uint16_t Crc16Array(uint32_t ui32WordLen, const uint32_t *pui32Data)
Definition: sw_crc.c:537