// // srecord - manipulate eprom load files // Copyright (C) 2000-2002, 2006, 2007 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // // (I got this copy from http://www.gator.net/~garyg/C/CONTRIB/SNIP/ // but as always on the Internet, it is now gone. So use the // Wayback Machine, http://www.archive.org/, or google for "crc_32" // and you should find it fairly quickly. The same code also // appears in the ZModem sources, as well, but they seem to abuse // it slightly, and the way they initialize and terminate the CRC // doesn't give the same answers as the way everyone else uses it.) // // 32 BIT ANSI X3.66 CRC checksum // // This class may be used to compute the 32-bit CRC used as the frame // check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 and // FED-STD-1003, the U.S. versions of CCITT's X.25 link-level protocol). // The 32-bit FCS was added via the Federal Register, 1 June 1982, // p.23798. I presume but don't know for certain that this polynomial // is or will be included in CCITT V.41, which defines the 16-bit CRC // (often called CRC-CCITT) polynomial. FIPS PUB 78 says that the // 32-bit FCS reduces otherwise undetected errors by a factor of 10^-5 // over 16-bit FCS. // #include // // Portions of the code in the file are derived from code which is // ``Copyright (C) 1986 Gary S. Brown. You may use this program, or // code or tables extracted from it, as desired without restriction.'' // // First, the polynomial itself and its table of feedback terms. The // polynomial is // X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 // Note that we take it "backwards" and put the highest-order term in // the lowest-order bit. The X^32 term is "implied"; the LSB is the // X^31 term, etc. The X^0 term (usually shown as "+1") results in // the MSB being 1. // #define POLYNOMIAL 0xedb88320 // // Note that the usual hardware shift register implementation, which // is what we're using (we're merely optimizing it by doing eight-bit // chunks at a time) shifts bits into the lowest-order term. In our // implementation, that means shifting towards the right. Why do we // do it this way? Because the calculated CRC must be transmitted in // order from highest-order term to lowest-order term. UARTs transmit // characters in order from LSB to MSB. By storing the CRC this way, // we hand it to the UART in the order low-byte to high-byte; the UART // sends each low-bit to hight-bit; and the result is transmission bit // by bit from highest- to lowest-order term without requiring any bit // shuffling on our part. Reception works similarly. // // The feedback terms table consists of 256, 32-bit entries. // // The values must be right-shifted by eight bits by the "UPDC32" // logic; the shift must be unsigned (bring in zeroes). // static unsigned long table[256]; static void calculate_table() { int b, i; unsigned long v; for (b = 0; b < 256; ++b) { for (v = b, i = 8; --i >= 0; ) v = (v & 1) ? ((v >> 1) ^ POLYNOMIAL) : (v >> 1); table[b] = v; } } crc32::crc32() : state(0xFFFFFFFF) { if (!table[1]) calculate_table(); } crc32::crc32(const crc32 &arg) : state(arg.state) { } crc32 & crc32::operator=(const crc32 &arg) { if (this != &arg) { state = arg.state; } return *this; } crc32::~crc32() { } static inline unsigned long UPDC32(unsigned char octet, unsigned long crc) { // The original code had this as a #define return table[(crc ^ octet) & 0xFF] ^ (crc >> 8); } void crc32::next(unsigned char x) { state = UPDC32(x, state); } void crc32::nextbuf(const void *data, size_t nbytes) { const unsigned char *dp = (unsigned char *)data; while (nbytes > 0) { state = UPDC32(*dp, state); ++dp; --nbytes; } } unsigned long crc32::get() const { #if 1 return ~state; #else // // The crc_32.c program floating around on the Internet prints // two numbers. The first is calculated as follows (the second // is the CRC as returned 5 lines back). It appears to be an // attempt to embed the crc into the data, and tell you what // the CRC should be if you calculate the CRC over the data and // the CRC. However, it makes the assumption that you store // the CRC little-endian, and it doesn't do the final bit-not. // // To simulate this (or something very much like it) try // srec_cat -lecrc32 -lecrc32 // unsigned long temp = state; temp = UPDC32( ~state & 0xFF, temp); temp = UPDC32((~state >> 8) & 0xFF, temp); temp = UPDC32((~state >> 16) & 0xFF, temp); temp = UPDC32((~state >> 24) & 0xFF, temp); return temp; // I wonder why this isn't bit-not-ed? #endif }