/* This software is subject to the license described in the License.txt file included with this software distribution. You may not use this file except in compliance with this license. Copyright (c) Dynastream Innovations Inc. 2013 All rights reserved. */ #include "types.h" #include "crc.h" #include "config.h" ////////////////////////////////////////////////////////////////////////////////// // Private Definitions ////////////////////////////////////////////////////////////////////////////////// #define CRC32_POLYNOMIAL 0xEDB88320 ////////////////////////////////////////////////////////////////////////////////// // Public Functions ////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// UCHAR CRC_Calc8(const void *pvDataPtr_, ULONG ulSize_) { return CRC_UpdateCRC8(0, pvDataPtr_, ulSize_); } /////////////////////////////////////////////////////////////////////// UCHAR CRC_UpdateCRC8(UCHAR ucCRC_, const void *pvDataPtr_, ULONG ulSize_) { UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_; while (ulSize_) { ucCRC_ = CRC_Get8(ucCRC_, *pucDataPtr); pucDataPtr++; ulSize_--; } return ucCRC_; } /////////////////////////////////////////////////////////////////////// UCHAR CRC_Get8(UCHAR ucCRC_, UCHAR ucByte_) { #if defined(AVR) __flash #endif static const UCHAR ucTable[256] = { 0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15, 0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D, 0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65, 0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D, 0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5, 0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD, 0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85, 0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD, 0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2, 0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA, 0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2, 0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A, 0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32, 0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A, 0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42, 0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A, 0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C, 0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4, 0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC, 0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4, 0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C, 0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44, 0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C, 0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34, 0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B, 0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63, 0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B, 0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13, 0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB, 0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83, 0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB, 0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3 }; return ucTable[ucCRC_ ^ ucByte_]; } /////////////////////////////////////////////////////////////////////// USHORT CRC_Calc16(const void *pvDataPtr_, ULONG ulSize_) { return CRC_UpdateCRC16(0, pvDataPtr_, ulSize_); } /////////////////////////////////////////////////////////////////////// USHORT CRC_UpdateCRC16(USHORT usCRC_, const volatile void *pvDataPtr_, ULONG ulSize_) { UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_; while (ulSize_) { usCRC_ = CRC_Get16(usCRC_, *pucDataPtr); pucDataPtr++; ulSize_--; } return usCRC_; } /////////////////////////////////////////////////////////////////////// // Optimized 8051 compatible /////////////////////////////////////////////////////////////////////// #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma location="DSI_BOOT_CODE" #endif USHORT CRC_UpdateCRC16Short(USHORT usCRC_, UCHAR MEM_TYPE *pucDataPtr_, USHORT usSize_) { while (usSize_) { usCRC_ = CRC_Get16(usCRC_, *pucDataPtr_); pucDataPtr_++; usSize_--; } return usCRC_; } /////////////////////////////////////////////////////////////////////// #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma location="DSI_BOOT_CODE" #endif USHORT CRC_Get16(USHORT usCRC_, UCHAR ucByte_) { #if defined(AVR) __flash #endif #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma memory = constseg(DSI_BOOT_DATA16_C) #endif static const USHORT ausCRC16Table[16] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma memory = default #endif USHORT usTemp; // compute checksum of lower four bits of byte usTemp = ausCRC16Table[usCRC_ & 0xF]; usCRC_ = (usCRC_ >> 4) & 0x0FFF; usCRC_ = usCRC_ ^ usTemp ^ ausCRC16Table[ucByte_ & 0x0F]; // now compute checksum of upper four bits of byte usTemp = ausCRC16Table[usCRC_ & 0xF]; usCRC_ = (usCRC_ >> 4) & 0x0FFF; usCRC_ = usCRC_ ^ usTemp ^ ausCRC16Table[(ucByte_ >> 4) & 0x0F]; return usCRC_; } /////////////////////////////////////////////////////////////////////// ULONG CRC_Calc32(const void *pvDataPtr_, ULONG ulSize_) { return CRC_UpdateCRC32(0, pvDataPtr_, ulSize_); } #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma location="DSI_BOOT_CODE" #endif /////////////////////////////////////////////////////////////////////// ULONG CRC_UpdateCRC32(ULONG ulCRC_, const void *pvDataPtr_, ULONG ulSize_) { ULONG ulTemp1; ULONG ulTemp2; UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_; while (ulSize_-- != 0) { ulTemp1 = (ulCRC_ >> 8) & 0x00FFFFFFL; ulTemp2 = CRC_Get32(((UCHAR) ulCRC_ ^ *pucDataPtr++) & 0xff); ulCRC_ = ulTemp1 ^ ulTemp2; } return ulCRC_; } #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE) #pragma location="DSI_BOOT_CODE" #endif /////////////////////////////////////////////////////////////////////// ULONG CRC_Get32(UCHAR ucByte) { UCHAR ucIndex; ULONG ulCRC; ulCRC = (ULONG) ucByte; for (ucIndex = 8; ucIndex > 0; ucIndex--) { if (ulCRC & 1) ulCRC = (ulCRC >> 1) ^ CRC32_POLYNOMIAL; else ulCRC >>= 1; } return ulCRC; }