1 //*****************************************************************************
2 //
3 // sw_crc.c - Software CRC functions.
4 //
5 // Copyright (c) 2010-2020 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.2.0.295 of the Tiva Peripheral Driver Library.
37 //
38 //*****************************************************************************
39 
40 //*****************************************************************************
41 //
42 //! \addtogroup sw_crc_api
43 //! @{
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 //
234 //! Calculates the CRC-8-CCITT of an array of bytes.
235 //!
236 //! \param ui8Crc is the starting CRC-8-CCITT value.
237 //! \param pui8Data is a pointer to the data buffer.
238 //! \param ui32Count is the number of bytes in the data buffer.
239 //!
240 //! This function is used to calculate the CRC-8-CCITT of the input buffer.
241 //! The CRC-8-CCITT is computed in a running fashion, meaning that the entire
242 //! data block that is to have its CRC-8-CCITT computed does not need to be
243 //! supplied all at once.  If the input buffer contains the entire block of
244 //! data, then \b ui8Crc should be set to 0.  If, however, the entire block of
245 //! data is not available, then \b ui8Crc should be set to 0 for the first
246 //! portion of the data, and then the returned value should be passed back in
247 //! as \b ui8Crc for the next portion of the data.
248 //!
249 //! For example, to compute the CRC-8-CCITT of a block that has been split into
250 //! three pieces, use the following:
251 //!
252 //! \verbatim
253 //!     ui8Crc = Crc8CCITT(0, pui8Data1, ui32Len1);
254 //!     ui8Crc = Crc8CCITT(ui8Crc, pui8Data2, ui32Len2);
255 //!     ui8Crc = Crc8CCITT(ui8Crc, pui8Data3, ui32Len3);
256 //! \endverbatim
257 //!
258 //! Computing a CRC-8-CCITT in a running fashion is useful in cases where the
259 //! data is arriving via a serial link (for example) and is therefore not all
260 //! available at one time.
261 //!
262 //! \return The CRC-8-CCITT of the input data.
263 //
264 //*****************************************************************************
265 uint8_t
Crc8CCITT(uint8_t ui8Crc,const uint8_t * pui8Data,uint32_t ui32Count)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 //
379 //! Calculates the CRC-16 of an array of bytes.
380 //!
381 //! \param ui16Crc is the starting CRC-16 value.
382 //! \param pui8Data is a pointer to the data buffer.
383 //! \param ui32Count is the number of bytes in the data buffer.
384 //!
385 //! This function is used to calculate the CRC-16 of the input buffer.  The
386 //! CRC-16 is computed in a running fashion, meaning that the entire data block
387 //! that is to have its CRC-16 computed does not need to be supplied all at
388 //! once.  If the input buffer contains the entire block of data, then
389 //! \b ui16Crc should be set to 0.  If, however, the entire block of data is
390 //! not available, then \b ui16Crc should be set to 0 for the first portion of
391 //! the data, and then the returned value should be passed back in as
392 //! \b ui16Crc for the next portion of the data.
393 //!
394 //! For example, to compute the CRC-16 of a block that has been split into
395 //! three pieces, use the following:
396 //!
397 //! \verbatim
398 //!     ui16Crc = Crc16(0, pui8Data1, ui32Len1);
399 //!     ui16Crc = Crc16(ui16Crc, pui8Data2, ui32Len2);
400 //!     ui16Crc = Crc16(ui16Crc, pui8Data3, ui32Len3);
401 //! \endverbatim
402 //!
403 //! Computing a CRC-16 in a running fashion is useful in cases where the data
404 //! is arriving via a serial link (for example) and is therefore not all
405 //! available at one time.
406 //!
407 //! \return The CRC-16 of the input data.
408 //
409 //*****************************************************************************
410 uint16_t
Crc16(uint16_t ui16Crc,const uint8_t * pui8Data,uint32_t ui32Count)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 //
524 //! Calculates the CRC-16 of an array of words.
525 //!
526 //! \param ui32WordLen is the length of the array in words (the number of bytes
527 //! divided by 4).
528 //! \param pui32Data is a pointer to the data buffer.
529 //!
530 //! This function is a wrapper around the running CRC-16 function, providing
531 //! the CRC-16 for a single block of data.
532 //!
533 //! \return The CRC-16 of the input data.
534 //
535 //*****************************************************************************
536 uint16_t
Crc16Array(uint32_t ui32WordLen,const uint32_t * pui32Data)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 //
547 //! Calculates three CRC-16s of an array of words.
548 //!
549 //! \param ui32WordLen is the length of the array in words (the number of bytes
550 //! divided by 4).
551 //! \param pui32Data is a pointer to the data buffer.
552 //! \param pui16Crc3 is a pointer to an array in which to place the three
553 //! CRC-16 values.
554 //!
555 //! This function is used to calculate three CRC-16s of the input buffer; the
556 //! first uses every byte from the array, the second uses only the even-index
557 //! bytes from the array (in other words, bytes 0, 2, 4, etc.), and the third
558 //! uses only the odd-index bytes from the array (in other words, bytes 1, 3,
559 //! 5, etc.).
560 //!
561 //! \return None
562 //
563 //*****************************************************************************
564 void
Crc16Array3(uint32_t ui32WordLen,const uint32_t * pui32Data,uint16_t * pui16Crc3)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 //
619 //! Calculates the CRC-32 of an array of bytes.
620 //!
621 //! \param ui32Crc is the starting CRC-32 value.
622 //! \param pui8Data is a pointer to the data buffer.
623 //! \param ui32Count is the number of bytes in the data buffer.
624 //!
625 //! This function is used to calculate the CRC-32 of the input buffer.  The
626 //! CRC-32 is computed in a running fashion, meaning that the entire data block
627 //! that is to have its CRC-32 computed does not need to be supplied all at
628 //! once.  If the input buffer contains the entire block of data, then
629 //! \b ui32Crc should be set to 0xFFFFFFFF.  If, however, the entire block of
630 //! data is not available, then \b ui32Crc should be set to 0xFFFFFFFF for the
631 //! first portion of the data, and then the returned value should be passed
632 //! back in as \b ui32Crc for the next portion of the data.  Once all data has
633 //! been passed to the function, the final CRC-32 can be obtained by inverting
634 //! the last returned value.
635 //!
636 //! For example, to compute the CRC-32 of a block that has been split into
637 //! three pieces, use the following:
638 //!
639 //! \verbatim
640 //!     ui32Crc = Crc32(0xFFFFFFFF, pui8Data1, ui32Len1);
641 //!     ui32Crc = Crc32(ui32Crc, pui8Data2, ui32Len2);
642 //!     ui32Crc = Crc32(ui32Crc, pui8Data3, ui32Len3);
643 //!     ui32Crc ^= 0xFFFFFFFF;
644 //! \endverbatim
645 //!
646 //! Computing a CRC-32 in a running fashion is useful in cases where the data
647 //! is arriving via a serial link (for example) and is therefore not all
648 //! available at one time.
649 //!
650 //! \return The accumulated CRC-32 of the input data.
651 //
652 //*****************************************************************************
653 uint32_t
Crc32(uint32_t ui32Crc,const uint8_t * pui8Data,uint32_t ui32Count)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.
768 //! @}
769 //
770 //*****************************************************************************
771