| Xmega IEC60730 Class B Library 1.0 |

All Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
classb_crc_sw.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /**
3 * \file
4 *
5 * \brief Functions for computing 32- and 16-bit CRC for EEPROM and Flash.
6 *
7 * \par Application note:
8 * AVR1610: Guide to IEC60730 Class B compliance with XMEGA
9 *
10 * \par Documentation
11 * For comprehensive code documentation, supported compilers, compiler
12 * settings and supported devices see readme.html
13 *
14 * \author
15 * Atmel Corporation: http://www.atmel.com \n
16 * Support email: avr@atmel.com
17 *
18 * Copyright (C) 2012 Atmel Corporation. All rights reserved.
19 *
20 * \page License
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions are met:
24 *
25 * 1. Redistributions of source code must retain the above copyright notice,
26 * this list of conditions and the following disclaimer.
27 *
28 * 2. Redistributions in binary form must reproduce the above copyright notice,
29 * this list of conditions and the following disclaimer in the documentation
30 * and/or other materials provided with the distribution.
31 *
32 * 3. The name of Atmel may not be used to endorse or promote products derived
33 * from this software without specific prior written permission.
34 *
35 * 4. This software may only be redistributed and used in connection with an
36 * Atmel AVR product.
37 *
38 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
39 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
41 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
42 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
44 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
45 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
48 * DAMAGE.
49 */
50
51 //! \ingroup classb_crc_sw
52 //@{
53
54 #include "classb_crc_sw.h"
55
56
57 /******************* CRC16 Functions ******************/
58
59 #if (defined(CLASSB_CRC_USE_SW) && defined(CLASSB_CRC_16_BIT)) || defined(__DOXYGEN__)
60
61 #if defined(CRC_USE_16BIT_LOOKUP_TABLE) || defined(__DOXYGEN__)
62
63 //! Table for CCITT 16-bit CRC, stored in Flash
64 const uint16_t PROGMEM_DECLARE( CLASSB_CRC16Table[256] ) = {
65 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
66 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
67 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
68 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
69 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
70 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
71 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
72 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
73 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
74 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
75 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
76 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
77 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
78 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
79 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
80 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
81 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
82 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
83 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
84 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
85 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
86 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
87 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
88 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
89 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
90 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
91 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
92 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
93 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
94 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
95 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
96 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
97 };
98 #endif //defined(CRC_USE_16BIT_LOOKUP_TABLE)
99
100
101 /*! \brief Compute 16-bit CRC for EEPROM address range using table lookup.
102 *
103 * This function returns the 16-bit CRC of the specified EEPROM address range.
104 *
105 * \param origDataptr Address of EEPROM location to start CRC computation at.
106 * \param numBytes Number of bytes of the data.
107 * \param pchecksum Pointer to the checksum stored in EEPROM.
108 *
109 * \note No sanity checking of addresses is done.
110 */
111 uint16_t CLASSB_CRC16_EEPROM_SW (eepromptr_t origDataptr, crcbytenum_t numBytes, eeprom_uint16ptr_t pchecksum)
112 {
113 eeprom_uint8ptr_t dataptr = origDataptr;
114 uint16_t remainder = CRC16_INITIAL_REMAINDER;
115 uint8_t dataTemp;
116
117 // Ensure that EEPROM is memory mapped.
118 CLASSB_EEMAP_BEGIN();
119 dataptr += MAPPED_EEPROM_START;
120
121 // Compute CRC for the specified data.
122 for (; numBytes != 0; numBytes--)
123 {
124 dataTemp = *dataptr++;
125
126 #ifdef CRC_USE_16BIT_LOOKUP_TABLE
127 CLASSB_CRC_TABLE_16(dataTemp, remainder, CLASSB_CRC16Table);
128 #else
129 CLASSB_CRC(dataTemp, remainder, CRC16_POLYNOMIAL, 16);
130 #endif
131 }
132
133 #if defined(__ICCAVR__)
134 // Disable memory mapping of EEPROM, if necessary.
135 CLASSB_EEMAP_END();
136 // Compare checksums and handle error if necessary.
137 if ( remainder != *pchecksum)
138 CLASSB_ERROR_HANDLER_CRC();
139 #elif defined(__GCC__)
140 // Compare checksums and handle error if necessary.
141 if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
142 CLASSB_ERROR_HANDLER_CRC();
143 // Disable memory mapping of EEPROM, if necessary.
144 CLASSB_EEMAP_END();
145 #endif
146
147 return (remainder);
148 }
149
150
151 /*! \brief Compute 16-bit CRC for Flash address range using table lookup.
152 *
153 * This function returns the 16-bit CRC of the specified Flash address range.
154 *
155 * \param origDataptr Address of Flash location to start CRC computation at.
156 * \param numBytes Number of bytes of the data.
157 * \param pchecksum Pointer to the checksum stored in EEPROM.
158 *
159 * \note No sanity checking of addresses is done.
160 */
161 uint16_t CLASSB_CRC16_Flash_SW (flashptr_t origDataptr, crcbytenum_t numBytes, eeprom_uint16ptr_t pchecksum)
162 {
163 flash_uint8ptr_t dataptr = origDataptr;
164 uint16_t remainder = CRC16_INITIAL_REMAINDER;
165 uint8_t dataTemp;
166
167 // Compute CRC for the specified data.
168 for (; numBytes != 0; numBytes--)
169 {
170
171 #if (PROGMEM_SIZE >= 0x10000UL)
172 dataTemp = PROGMEM_READ_BYTE_FAR(dataptr++);
173 #else
174 dataTemp = PROGMEM_READ_BYTE(dataptr++);
175 #endif
176
177 #if defined(CRC_USE_16BIT_LOOKUP_TABLE)
178 CLASSB_CRC_TABLE_16(dataTemp, remainder, CLASSB_CRC16Table);
179 #else
180 CLASSB_CRC(dataTemp, remainder, CRC16_POLYNOMIAL, 16);
181 #endif
182 }
183
184 #if defined(__ICCAVR__)
185 // Compare checksums and handle error if necessary.
186 if ( remainder != *pchecksum)
187 CLASSB_ERROR_HANDLER_CRC();
188 #elif defined(__GCC__)
189 // Ensure that EEPROM is memory mapped.
190 CLASSB_EEMAP_BEGIN();
191 // Compare checksums and handle error if necessary.
192 if ( remainder != *(eeprom_uint16ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
193 CLASSB_ERROR_HANDLER_CRC();
194 // Disable memory mapping of EEPROM, if necessary.
195 CLASSB_EEMAP_END();
196 #endif
197
198 return (remainder);
199 }
200 #endif // defined(CLASSB_CRC_USE_SW) && defined(CLASSB_CRC_16_BIT)
201
202
203
204 /******************* CRC32 Functions ******************/
205 #if (defined(CLASSB_CRC_USE_SW) && defined(CLASSB_CRC_32_BIT)) || defined(__DOXYGEN__)
206
207 #if defined(CRC_USE_32BIT_LOOKUP_TABLE) || defined(__DOXYGEN__)
208
209 //! Table for IEE802.3 32-bit CRC, stored in Flash
210 const uint32_t PROGMEM_DECLARE( CLASSB_CRC32Table[256] ) = {
211 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
212 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
213 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
214 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
215 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
216 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
217 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
218 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
219 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
220 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
221 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
222 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
223 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
224 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
225 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
226 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
227 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
228 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
229 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
230 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
231 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
232 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
233 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
234 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
235 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
236 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
237 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
238 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
239 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
240 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
241 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
242 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
243 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
244 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
245 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
246 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
247 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
248 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
249 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
250 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
251 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
252 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
253 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
254 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
255 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
256 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
257 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
258 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
259 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
260 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
261 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
262 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
263 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
264 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
265 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
266 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
267 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
268 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
269 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
270 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
271 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
272 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
273 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
274 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
275 };
276 #endif //defined(CRC_USE_32BIT_LOOKUP_TABLE)
277
278
279 /*! \brief Compute 32-bit CRC for EEPROM address range using table lookup.
280 *
281 * This function returns the 32-bit CRC of the specified EEPROM address range.
282 *
283 * \param origDataptr Address of EEPROM location to start CRC computation at.
284 * \param numBytes Number of bytes of the data.
285 * \param pchecksum Pointer to the checksum stored in EEPROM.
286 *
287 * \note No sanity checking of addresses is done.
288 */
289 uint32_t CLASSB_CRC32_EEPROM_SW (eepromptr_t origDataptr, crcbytenum_t numBytes, eeprom_uint32ptr_t pchecksum)
290 {
291 eeprom_uint8ptr_t dataptr = origDataptr;
292 uint32_t remainder = CRC32_INITIAL_REMAINDER;
293 uint8_t dataTemp;
294
295 // Ensure that EEPROM is memory mapped.
296 CLASSB_EEMAP_BEGIN();
297 dataptr += MAPPED_EEPROM_START;
298
299 // Compute CRC for the specified data.
300 for (; numBytes != 0; numBytes--)
301 {
302 dataTemp = *dataptr++;
303 #if defined(CRC_USE_32BIT_LOOKUP_TABLE)
304 CLASSB_CRC_REFL_TABLE_32(dataTemp, remainder, CLASSB_CRC32Table);
305 #else
306 CLASSB_CRC_REFL(dataTemp, remainder, CRC32_POLYNOMIAL, 32);
307 #endif
308 }
309
310 #ifdef CRC32_FINAL_XOR_VALUE
311 remainder ^= CRC32_FINAL_XOR_VALUE;
312 #endif
313
314 #if defined(__ICCAVR__)
315 // Disable memory mapping of EEPROM, if necessary.
316 CLASSB_EEMAP_END();
317 // Compare checksums and handle error if necessary.
318 if ( remainder != *pchecksum)
319 CLASSB_ERROR_HANDLER_CRC();
320 #elif defined(__GCC__)
321 // Compare checksums and handle error if necessary.
322 if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
323 CLASSB_ERROR_HANDLER_CRC();
324 // Disable memory mapping of EEPROM, if necessary.
325 CLASSB_EEMAP_END();
326 #endif
327
328 return (remainder);
329 }
330
331
332 /*! \brief Compute 32-bit CRC for Flash address range using table lookup.
333 *
334 * This function returns the 32-bit CRC of the specified Flash address range.
335 *
336 * \param origDataptr Address of Flash location to start CRC computation at.
337 * \param numBytes Number of bytes of the data.
338 * \param pchecksum Pointer to the checksum stored in EEPROM.
339 *
340 * \note No sanity checking of addresses is done.
341 */
342 uint32_t CLASSB_CRC32_Flash_SW (flashptr_t origDataptr, crcbytenum_t numBytes, eeprom_uint32ptr_t pchecksum)
343 {
344 flash_uint8ptr_t dataptr = origDataptr;
345 uint32_t remainder = CRC32_INITIAL_REMAINDER;
346 uint8_t dataTemp;
347
348 // Compute CRC for the specified data.
349 for (; numBytes != 0; numBytes--)
350 {
351
352 #if (PROGMEM_SIZE >= 0x10000UL)
353 dataTemp = PROGMEM_READ_BYTE_FAR(dataptr++);
354 #else
355 dataTemp = PROGMEM_READ_BYTE(dataptr++);
356 #endif
357
358 #if defined(CRC_USE_32BIT_LOOKUP_TABLE)
359 CLASSB_CRC_REFL_TABLE_32(dataTemp, remainder, CLASSB_CRC32Table);
360 #else
361 CLASSB_CRC_REFL(dataTemp, remainder, CRC32_POLYNOMIAL, 32);
362 #endif
363
364 }
365
366 #ifdef CRC32_FINAL_XOR_VALUE
367 remainder ^= CRC32_FINAL_XOR_VALUE;
368 #endif
369
370 #if defined(__ICCAVR__)
371 // Compare checksums and handle error if necessary.
372 if ( remainder != *pchecksum)
373 CLASSB_ERROR_HANDLER_CRC();
374 #elif defined(__GCC__)
375 // Ensure that EEPROM is memory mapped.
376 CLASSB_EEMAP_BEGIN();
377 // Compare checksums and handle error if necessary.
378 if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
379 CLASSB_ERROR_HANDLER_CRC();
380 // Disable memory mapping of EEPROM, if necessary.
381 CLASSB_EEMAP_END();
382 #endif
383
384 return (remainder);
385 }
386
387
388 #endif // defined(CLASSB_CRC_USE_SW) && defined(CLASSB_CRC_32_BIT)
389 //@}