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.
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.
136  // Compare checksums and handle error if necessary.
137  if ( remainder != *pchecksum)
139  #elif defined(__GCC__)
140  // Compare checksums and handle error if necessary.
141  if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
143  // Disable memory mapping of EEPROM, if necessary.
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)
188  #elif defined(__GCC__)
189  // Ensure that EEPROM is memory mapped.
191  // Compare checksums and handle error if necessary.
192  if ( remainder != *(eeprom_uint16ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
194  // Disable memory mapping of EEPROM, if necessary.
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.
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.
317  // Compare checksums and handle error if necessary.
318  if ( remainder != *pchecksum)
320  #elif defined(__GCC__)
321  // Compare checksums and handle error if necessary.
322  if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
324  // Disable memory mapping of EEPROM, if necessary.
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)
374  #elif defined(__GCC__)
375  // Ensure that EEPROM is memory mapped.
377  // Compare checksums and handle error if necessary.
378  if ( remainder != *(eeprom_uint32ptr_t)(MAPPED_EEPROM_START + (uintptr_t) pchecksum))
380  // Disable memory mapping of EEPROM, if necessary.
382  #endif
383 
384  return (remainder);
385 }
386 
387 
388 #endif // defined(CLASSB_CRC_USE_SW) && defined(CLASSB_CRC_32_BIT)
389 //@}