Xmega IEC60730 Class B Library  1.0
 All Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
classb_crc_sw.h
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /**
3  * \file
4  *
5  * \brief Definitions and settings for the CRC implemented in software.
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 #ifndef __CRC_H_SW__
52 #define __CRC_H_SW__
53 
54 #include "avr_compiler.h"
55 #include "classb_crc.h"
56 
57 //! \ingroup classb_crc
58 //!
59 //! \defgroup classb_crc_sw CRC software implementation
60 //!
61 //! \brief CRC computations implemented in software.
62 //!
63 //! The CPU reads the data and computes the CRC checksum. There are two available
64 //! methods:
65 //! - Lookup table: this uses a CRC lookup table to speed up the computations.
66 //! The lookup table requires 512 (for 16 bit) or 1024 (for 32 bit) bytes of flash memory.
67 //! - Direct computation: this calculates the checksum for each byte using a polynomial
68 //! division each time it is called. This version occupies no space in flash memory,
69 //! but is 3.5-4x slower than lookup table method.
70 //!
71 //! The CRC32-polynomial is in the reflected form (0xEDB88320) in the software
72 //! implementation. The initial remainder is 0xFFFFFFFF, and the generated checksum
73 //! is bit-reversed and complemented (in compliance with IEE802.3). The CCITT polynomial
74 //! used is 0x1021, with 0x0000 as initial remainder. In this case the checksum is neither
75 //! bit reversed nor complemented.
76 //!
77 
78 //@{
79 
80 /**
81  * \name Settings for CRC software implementation
82  *
83  * \brief These symbols are used to choose between lookup table or direct computation.
84  * They should be defined for lookup table implementation and commented out otherwise.
85  *
86  */
87 //@{
88 #ifdef __DOXYGEN__
89  //! Select the lookup table method for 16-bit CRC
90  #define CRC_USE_16BIT_LOOKUP_TABLE
91  //! Select the lookup table method for 32-bit CRC
92  #define CRC_USE_32BIT_LOOKUP_TABLE
93 #else
94  #define CRC_USE_16BIT_LOOKUP_TABLE
95  #define CRC_USE_32BIT_LOOKUP_TABLE
96 #endif
97 //@}
98 
99 
100 /**
101  * \internal
102  *
103  * \name This settings should not be modified
104  *
105  * \brief This options make sure that the CRC computation complies with the
106  * standard 16-bit CCITT CRC and IEE802.3 32-bit CRC.
107  */
108 //@{
109 //! \internal \brief Polynomial used for computation of CRC16 (software, not lookup table)
110 #define CRC16_POLYNOMIAL 0x1021 // CCITT: 0x1021 <-> x^16 + x^12 + x^5 + 1
111 //! \internal \brief Polynomial used for computation of CRC32 (software, not lookup table)
112 #define CRC32_POLYNOMIAL 0xEDB88320UL //IEE802.3: 0xEDB88320 is the reflection of 0x04C11DB7
113 //! \internal \brief Final XOR Value for CRC32
114 #define CRC32_FINAL_XOR_VALUE 0xFFFFFFFF
115 //@}
116 
117 //! \internal
118 //!
119 //! \name Macros used for CRC computation
120 
121 //@{
122 
123 /*! \internal\brief Update CRC value for one input byte.
124  *
125  * \note This macro works for both 16 and 32 bit CRC.
126  *
127  * \param data Input data byte.
128  * \param crc Variable that holds the CRC value.
129  * \param poly CRC polynomial.
130  * \param crcbits Number of CRC bits.
131  */
132 #define CLASSB_CRC(data,crc,poly,crcbits) { \
133  /* Bring the next byte into the checksum. */ \
134  crc ^= ((uint32_t)data << (crcbits - 8)); \
135 \
136  uint8_t bit; \
137 \
138  /* Perform modulo-2 division. */ \
139  for (bit = 8; bit > 0; --bit) { \
140  /* ..only if MSB is set. */ \
141  if ( crc & ((uint32_t)1 << (crcbits - 1)) ) { \
142  crc = (crc << 1) ^ poly; \
143  } \
144  else { \
145  crc <<= 1; \
146  } \
147  } \
148 }
149 
150 /*! \internal \brief Update CRC value for one input byte (reflected polynomial).
151  *
152  * \note This macro works for both 16 and 32 bit CRC.
153  *
154  * \param data Input data byte.
155  * \param crc Variable that holds the CRC value.
156  * \param poly CRC polynomial.
157  * \param crcbits Number of CRC bits.
158  */
159 #define CLASSB_CRC_REFL(data,crc,poly,crcbits) { \
160  /* Bring next byte into the checksum. */ \
161  crc ^= (uint32_t)data; \
162 \
163  uint8_t bit; \
164 \
165  /* Perform modulo-2 division. */ \
166  for (bit = 8; bit > 0; --bit) { \
167  /* ..only if LSB is set. */ \
168  if (crc & 0x01) { \
169  crc = (crc >> 1) ^ poly; \
170  } \
171  else { \
172  crc >>= 1; \
173  } \
174  } \
175 }
176 
177 /*! \internal \brief Update 32-bit CRC value for one input byte (reflected polynomial).
178  *
179  * \note This macro assumes that the CRC lookup table is located in the lower
180  * 64 kB address range of Flash.
181  *
182  * \param data Input data byte.
183  * \param crc Variable that holds the CRC value.
184  * \param table Table that contains pre-calculated CRC values.
185  */
186 #define CLASSB_CRC_REFL_TABLE_32(data,crc,table) { \
187  data ^= crc & 0xFF; \
188  crc = PROGMEM_READ_DWORD(&table[data]) ^ (crc >> 8); \
189 }
190 
191 /*! \internal\brief Update 16-bit CRC value for one input byte.
192  *
193  * \note This macro assumes that the CRC lookup table is located in the lower
194  * 64 kB address range of Flash.
195  *
196  * \param data Input data byte.
197  * \param crc Variable that holds the CRC value.
198  * \param table Table that contains pre-calculated CRC values.
199  */
200 #define CLASSB_CRC_TABLE_16(data,crc,table) { \
201  data ^= crc >> (16 - 8); \
202  crc = PROGMEM_READ_WORD(&table[data]) ^ (crc << 8); \
203 }
204 
205 //@}
206 
207 //! \name CRC tests
208 //!
209 //! \brief Invariant memory tests based on CRC that are compliant with IEC60730 Class B.
210 //@{
211 uint16_t CLASSB_CRC16_EEPROM_SW (eepromptr_t dataptr, const crcbytenum_t numBytes, eeprom_uint16ptr_t pchecksum);
212 uint16_t CLASSB_CRC16_Flash_SW (flashptr_t dataptr, const crcbytenum_t numBytes, eeprom_uint16ptr_t pchecksum);
213 
214 uint32_t CLASSB_CRC32_EEPROM_SW (eepromptr_t dataptr, const crcbytenum_t numBytes, eeprom_uint32ptr_t pchecksum);
215 uint32_t CLASSB_CRC32_Flash_SW (flashptr_t dataptr, const crcbytenum_t numBytes, eeprom_uint32ptr_t pchecksum);
216 //@}
217 
218 
219 //@}
220 
221 #endif