1 // 2 // srecord - manipulate eprom load files 3 // Copyright (C) 2000-2003, 2006-2010, 2012 Peter Miller 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation; either version 3 of the License, or (at 8 // your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // 19 // See http://www.joegeluso.com/software/articles/ccitt.htm for a great 20 // write-up on the CRC16 calculation. 21 // 22 23 #ifndef SRECORD_CRC16_H 24 #define SRECORD_CRC16_H 25 26 #include <stddef.h> 27 28 namespace srecord 29 { 30 31 /** 32 * The crc16 class is used to represent the running value of a 16-bit 33 * cyclic redundancy check of series of bytes. 34 * 35 * Note: this CRC16 works for systems that process the leaast 36 * significant bit of each byte first, and working to wards the most 37 * significant bit. 38 * 39 * If you were expecting MSB first (you may not even know it) this 40 * code will give you "wrong" answers. Try using the bitrev filter. 41 */ 42 class crc16 43 { 44 public: 45 // See http://en.wikipedia.org/wiki/Cyclic_redundancy_check 46 // for table of polynomials. 47 enum 48 { 49 /** 50 * X.25, V.41, HDLC, XMODEM, Bluetooth, SD, CRC-CCITT 51 */ 52 polynomial_ccitt = 0x1021, 53 54 /** 55 * CRC-16-IBM, Bisync, Modbus, USB, ANSI X3.28, CRC-16-ANSI 56 */ 57 polynomial_ansi = 0x8005, 58 59 /** 60 * CRC-16-DNP, DNP, IEC 870, M-Bus 61 */ 62 polynomial_dnp = 0x3D65, 63 64 /** 65 * CRC-16-DECT 66 */ 67 polynomial_dect = 0x0589, 68 69 /** 70 * CRC-16-T10-DIF, SCSI DIF 71 */ 72 polynomial_t10_dif = 0x8BB7, 73 }; 74 75 /** 76 * The polynomial_by_name class method is used to take the name 77 * of a CRC-16 polynamlial, and return the value of the CRC-16 78 * polynomial corresponding to that name. 79 */ 80 static int polynomial_by_name(const char *name); 81 82 enum seed_mode_t 83 { 84 seed_mode_ccitt, 85 seed_mode_xmodem, 86 seed_mode_broken 87 }; 88 89 /** 90 * The destructor. 91 */ 92 virtual ~crc16(); 93 94 enum bit_direction_t 95 { 96 bit_direction_most_to_least, 97 bit_direction_least_to_most, 98 }; 99 100 /** 101 * The default constructor. 102 * 103 * @param seed_mode 104 * This selects which CRC16 calculation seed is to be used. 105 * @param augment 106 * This is true if the 16-zero-bit augmentation is desired. 107 * This is the default. False if no augmentation is desired. 108 * @param polynomial 109 * The checksum polynomial. 110 * @param bitdir 111 * The direction of bits in a characters as they pass through 112 * the algorithm. 113 */ 114 crc16(seed_mode_t seed_mode = seed_mode_ccitt, bool augment = true, 115 unsigned short polynomial = polynomial_ccitt, 116 bit_direction_t bitdir = bit_direction_most_to_least); 117 118 /** 119 * The copy constructor. 120 */ 121 crc16(const crc16 &); 122 123 /** 124 * The assignment operator. 125 */ 126 crc16 &operator=(const crc16 &); 127 128 /** 129 * The get method is used to obtain the running value of the cyclic 130 * redundancy check. 131 */ 132 unsigned short get() const; 133 134 /** 135 * The next method is used to advance the state by one byte. 136 */ 137 void next(unsigned char); 138 139 /** 140 * The nextbuf method is used to advance the state by a series of bytes. 141 */ 142 void nextbuf(const void *, size_t); 143 144 /** 145 * The print_table method may be used to print the table being used. 146 * This is principally for debugging the table generation process. 147 */ 148 void print_table(void) const; 149 150 private: 151 /** 152 * The state instance variable is used to remember the running 153 * value of the 16-bit cyclic redundancy check. 154 */ 155 unsigned short state; 156 157 /** 158 * The augment instance variable is used to remember whether or 159 * not the 16 zero bits of augmentation are to be processed before 160 * reporting the result. 161 */ 162 bool augment; 163 164 /** 165 * The polynomial instance variable is used to remember the CRC 166 * polynomial being calculated with. Note that if the bitdir is 167 * low-to-high then the bits in the polynomial will be reversed. 168 */ 169 unsigned short polynomial; 170 171 /** 172 * The bitdir instance variable is sued to remember the direction 173 * of bits in a characters as they pass through the algorithm. 174 */ 175 bit_direction_t bitdir; 176 177 /** 178 * The table instance variable is used to remember the results of 8 179 * shift-and-process operations for each byte value. This is used 180 * to improve efficiency. It is filled in the the #calculate_table 181 * method, called from the constructor. 182 */ 183 unsigned short table[256]; 184 185 /** 186 * The calculate_table method is called by the constructor to fill 187 * in the #table instance variable. 188 */ 189 void calculate_table(void); 190 191 /** 192 * The updcrc method is to add another byte of data to the running 193 * CRC state. It is called by the #next and next_buf methods. 194 */ 195 inline unsigned short updcrc(unsigned char c, unsigned short state) const; 196 }; 197 198 }; 199 200 #endif // SRECORD_CRC16_H 201