crc.c 6.1 KB

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