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