crc.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2013
  6. All rights reserved.
  7. */
  8. #include "types.h"
  9. #include "crc.h"
  10. #include "config.h"
  11. //////////////////////////////////////////////////////////////////////////////////
  12. // Private Definitions
  13. //////////////////////////////////////////////////////////////////////////////////
  14. #define CRC32_POLYNOMIAL 0xEDB88320
  15. //////////////////////////////////////////////////////////////////////////////////
  16. // Public Functions
  17. //////////////////////////////////////////////////////////////////////////////////
  18. ///////////////////////////////////////////////////////////////////////
  19. UCHAR CRC_Calc8(const void *pvDataPtr_, ULONG ulSize_)
  20. {
  21. return CRC_UpdateCRC8(0, pvDataPtr_, ulSize_);
  22. }
  23. ///////////////////////////////////////////////////////////////////////
  24. UCHAR CRC_UpdateCRC8(UCHAR ucCRC_, const void *pvDataPtr_, ULONG ulSize_)
  25. {
  26. UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
  27. while (ulSize_)
  28. {
  29. ucCRC_ = CRC_Get8(ucCRC_, *pucDataPtr);
  30. pucDataPtr++;
  31. ulSize_--;
  32. }
  33. return ucCRC_;
  34. }
  35. ///////////////////////////////////////////////////////////////////////
  36. UCHAR CRC_Get8(UCHAR ucCRC_, UCHAR ucByte_)
  37. {
  38. #if defined(AVR)
  39. __flash
  40. #endif
  41. static const UCHAR ucTable[256] =
  42. {
  43. 0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,
  44. 0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,0x2D,
  45. 0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,
  46. 0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
  47. 0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,
  48. 0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,
  49. 0x90,0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,
  50. 0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,
  51. 0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,
  52. 0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
  53. 0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,
  54. 0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,
  55. 0x27,0x20,0x29,0x2E,0x3B,0x3C,0x35,0x32,
  56. 0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,
  57. 0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,
  58. 0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,
  59. 0x89,0x8E,0x87,0x80,0x95,0x92,0x9B,0x9C,
  60. 0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,
  61. 0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,
  62. 0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
  63. 0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,
  64. 0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,
  65. 0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,
  66. 0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,
  67. 0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,
  68. 0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,
  69. 0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,
  70. 0x06,0x01,0x08,0x0F,0x1A,0x1D,0x14,0x13,
  71. 0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,
  72. 0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
  73. 0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,
  74. 0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3
  75. };
  76. return ucTable[ucCRC_ ^ ucByte_];
  77. }
  78. ///////////////////////////////////////////////////////////////////////
  79. USHORT CRC_Calc16(const void *pvDataPtr_, ULONG ulSize_)
  80. {
  81. return CRC_UpdateCRC16(0, pvDataPtr_, ulSize_);
  82. }
  83. ///////////////////////////////////////////////////////////////////////
  84. USHORT CRC_UpdateCRC16(USHORT usCRC_, const volatile void *pvDataPtr_, ULONG ulSize_)
  85. {
  86. UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
  87. while (ulSize_)
  88. {
  89. usCRC_ = CRC_Get16(usCRC_, *pucDataPtr);
  90. pucDataPtr++;
  91. ulSize_--;
  92. }
  93. return usCRC_;
  94. }
  95. ///////////////////////////////////////////////////////////////////////
  96. // Optimized 8051 compatible
  97. ///////////////////////////////////////////////////////////////////////
  98. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  99. #pragma location="DSI_BOOT_CODE"
  100. #endif
  101. USHORT CRC_UpdateCRC16Short(USHORT usCRC_, UCHAR MEM_TYPE *pucDataPtr_, USHORT usSize_)
  102. {
  103. while (usSize_)
  104. {
  105. usCRC_ = CRC_Get16(usCRC_, *pucDataPtr_);
  106. pucDataPtr_++;
  107. usSize_--;
  108. }
  109. return usCRC_;
  110. }
  111. ///////////////////////////////////////////////////////////////////////
  112. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  113. #pragma location="DSI_BOOT_CODE"
  114. #endif
  115. USHORT CRC_Get16(USHORT usCRC_, UCHAR ucByte_)
  116. {
  117. #if defined(AVR)
  118. __flash
  119. #endif
  120. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  121. #pragma memory = constseg(DSI_BOOT_DATA16_C)
  122. #endif
  123. static const USHORT ausCRC16Table[16] =
  124. {
  125. 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
  126. 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
  127. };
  128. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  129. #pragma memory = default
  130. #endif
  131. USHORT usTemp;
  132. // compute checksum of lower four bits of byte
  133. usTemp = ausCRC16Table[usCRC_ & 0xF];
  134. usCRC_ = (usCRC_ >> 4) & 0x0FFF;
  135. usCRC_ = usCRC_ ^ usTemp ^ ausCRC16Table[ucByte_ & 0x0F];
  136. // now compute checksum of upper four bits of byte
  137. usTemp = ausCRC16Table[usCRC_ & 0xF];
  138. usCRC_ = (usCRC_ >> 4) & 0x0FFF;
  139. usCRC_ = usCRC_ ^ usTemp ^ ausCRC16Table[(ucByte_ >> 4) & 0x0F];
  140. return usCRC_;
  141. }
  142. ///////////////////////////////////////////////////////////////////////
  143. ULONG CRC_Calc32(const void *pvDataPtr_, ULONG ulSize_)
  144. {
  145. return CRC_UpdateCRC32(0, pvDataPtr_, ulSize_);
  146. }
  147. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  148. #pragma location="DSI_BOOT_CODE"
  149. #endif
  150. ///////////////////////////////////////////////////////////////////////
  151. ULONG CRC_UpdateCRC32(ULONG ulCRC_, const void *pvDataPtr_, ULONG ulSize_)
  152. {
  153. ULONG ulTemp1;
  154. ULONG ulTemp2;
  155. UCHAR *pucDataPtr = (UCHAR *) pvDataPtr_;
  156. while (ulSize_-- != 0)
  157. {
  158. ulTemp1 = (ulCRC_ >> 8) & 0x00FFFFFFL;
  159. ulTemp2 = CRC_Get32(((UCHAR) ulCRC_ ^ *pucDataPtr++) & 0xff);
  160. ulCRC_ = ulTemp1 ^ ulTemp2;
  161. }
  162. return ulCRC_;
  163. }
  164. #if defined(INCLUDE_BOOT_UPGRADE) && !defined(OFFLINE)
  165. #pragma location="DSI_BOOT_CODE"
  166. #endif
  167. ///////////////////////////////////////////////////////////////////////
  168. ULONG CRC_Get32(UCHAR ucByte)
  169. {
  170. UCHAR ucIndex;
  171. ULONG ulCRC;
  172. ulCRC = (ULONG) ucByte;
  173. for (ucIndex = 8; ucIndex > 0; ucIndex--)
  174. {
  175. if (ulCRC & 1)
  176. ulCRC = (ulCRC >> 1) ^ CRC32_POLYNOMIAL;
  177. else
  178. ulCRC >>= 1;
  179. }
  180. return ulCRC;
  181. }