crc.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*******************************************************************************
  2. * File Name : amt630hv120_crc.c
  3. * Author : Sim
  4. * Date First Issued : 12/28/2022
  5. * Description : This file provides all the CRC firmware functions.
  6. ********************************************************************************
  7. * History:
  8. * 12/28/2022: V0.1
  9. *******************************************************************************/
  10. /* Includes ------------------------------------------------------------------*/
  11. #include "chip.h"
  12. #include "crc.h"
  13. #define CRC_CTL_WIDTH32_START (1 << 10)
  14. #define CRC_CTL_WIDTH16_START (1 << 9)
  15. #define CRC_CTL_WIDTH8_START (1 << 8)
  16. #define CRC_CTL_INIT_EN (1 << 6)
  17. #define CRC_CTL_VECTMASK (3 << 2)
  18. #define CRC_CTL_VECT32 (0 << 2)
  19. #define CRC_CTL_VECT16 (1 << 2)
  20. #define CRC_CTL_VECT8 (2 << 2)
  21. static u32 c_poly8_g = 0x0000008e;
  22. static u32 c_poly16_g = 0x00008810;
  23. static u32 c_poly32_g = 0x82608edb;
  24. typedef union {
  25. u8 *buf8;
  26. u16 *buf16;
  27. u32 *buf32;
  28. } CrcDataBuf;
  29. typedef struct
  30. {
  31. volatile u32 EN;
  32. volatile u32 CTRL;
  33. volatile u32 DATA;
  34. volatile u32 INIT;
  35. volatile u32 RET;
  36. } CRC_TypeDef;
  37. #define CRC ((CRC_TypeDef*)REGS_CRC_BASE)
  38. typedef u32 (*crc_algo)(const void *buf, u32 len, u32 init,
  39. CrcPoly polyopt, CrcDataWidth widthopt);
  40. static u32 crc_soft(const void *buf, u32 len, u32 init,
  41. CrcPoly polyopt, CrcDataWidth widthopt)
  42. {
  43. CrcDataBuf tmpbuf;
  44. u8 tmpbit;
  45. u32 tmp = init;
  46. u32 result;
  47. int i;
  48. u32 poly = c_poly32_g;
  49. u32 width = 32;
  50. u32 shift = 31;
  51. if (widthopt == CRC_DATA_WIDTH8) {
  52. tmpbuf.buf8 = (u8*)buf;
  53. width = 8;
  54. } else if (widthopt == CRC_DATA_WIDTH16) {
  55. assert((((u32)buf | len) & 1) == 0);
  56. tmpbuf.buf16 = (u16*)buf;
  57. width = 16;
  58. len /= 2;
  59. } else if (widthopt == CRC_DATA_WIDTH32) {
  60. assert((((u32)buf | len) & 3) == 0);
  61. tmpbuf.buf32 = (u32*)buf;
  62. width = 32;
  63. len /= 4;
  64. }
  65. if (polyopt == CRC_POLY8) {
  66. poly = c_poly8_g;
  67. shift = 7;
  68. } else if (polyopt == CRC_POLY16) {
  69. poly = c_poly16_g;
  70. shift = 15;
  71. } else if (polyopt == CRC_POLY32) {
  72. poly = c_poly32_g;
  73. shift = 31;
  74. }
  75. while (len--) {
  76. for (i = 0; i < width; i++) {
  77. if (widthopt == CRC_DATA_WIDTH8)
  78. tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf8 >> i)) & 1;
  79. else if (widthopt == CRC_DATA_WIDTH16)
  80. tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf16 >> i)) & 1;
  81. else if (widthopt == CRC_DATA_WIDTH32)
  82. tmpbit = ((tmp >> shift) ^ (*tmpbuf.buf32 >> i)) & 1;
  83. if (tmpbit) {
  84. result = ((((tmp << 1) >> 1) ^ ((poly << 1) >> 1)) << 1) | 1;
  85. } else {
  86. result = tmp << 1;
  87. }
  88. tmp = result;
  89. }
  90. if (widthopt == CRC_DATA_WIDTH8)
  91. tmpbuf.buf8++;
  92. else if (widthopt == CRC_DATA_WIDTH16)
  93. tmpbuf.buf16++;
  94. else if (widthopt == CRC_DATA_WIDTH32)
  95. tmpbuf.buf32++;
  96. }
  97. return result;
  98. }
  99. u32 CRC_Calc(const void *buf, u32 len, u32 init,
  100. CrcPoly polyopt, CrcDataWidth widthopt)
  101. {
  102. CrcDataBuf tmpbuf;
  103. u32 result;
  104. int i;
  105. if (widthopt == CRC_DATA_WIDTH8) {
  106. tmpbuf.buf8 = (u8*)buf;
  107. } else if (widthopt == CRC_DATA_WIDTH16) {
  108. assert((((u32)buf | len) & 1) == 0);
  109. tmpbuf.buf16 = (u16*)buf;
  110. len /= 2;
  111. } else if (widthopt == CRC_DATA_WIDTH32) {
  112. assert((((u32)buf | len) & 3) == 0);
  113. tmpbuf.buf32 = (u32*)buf;
  114. len /= 4;
  115. }
  116. // if (sema_take(SEMA_GATE_CRC, portMAX_DELAY) != pdPASS) {
  117. // return 0xffffffff;
  118. // }
  119. CRC->INIT = init;
  120. CRC->CTRL |= CRC_CTL_INIT_EN;
  121. CRC->CTRL &= ~CRC_CTL_INIT_EN;
  122. CRC->CTRL &= ~CRC_CTL_VECTMASK;
  123. if (polyopt == CRC_POLY8)
  124. CRC->CTRL |= CRC_CTL_VECT8;
  125. else if (polyopt == CRC_POLY16)
  126. CRC->CTRL |= CRC_CTL_VECT16;
  127. else if (polyopt == CRC_POLY32)
  128. CRC->CTRL |= CRC_CTL_VECT32;
  129. if (widthopt == CRC_DATA_WIDTH8)
  130. CRC->CTRL |= CRC_CTL_WIDTH8_START;
  131. else if (widthopt == CRC_DATA_WIDTH16)
  132. CRC->CTRL |= CRC_CTL_WIDTH16_START;
  133. if (widthopt == CRC_DATA_WIDTH32)
  134. CRC->CTRL |= CRC_CTL_WIDTH32_START;
  135. for (i = 0; i < len; i++) {
  136. if (widthopt == CRC_DATA_WIDTH8)
  137. CRC->DATA = tmpbuf.buf8[i];
  138. else if (widthopt == CRC_DATA_WIDTH16)
  139. CRC->DATA = tmpbuf.buf16[i];
  140. else if (widthopt == CRC_DATA_WIDTH32)
  141. CRC->DATA = tmpbuf.buf32[i];
  142. }
  143. udelay(10);
  144. result = CRC->RET;
  145. if (widthopt == CRC_DATA_WIDTH8)
  146. CRC->CTRL &= ~CRC_CTL_WIDTH8_START;
  147. else if (widthopt == CRC_DATA_WIDTH16)
  148. CRC->CTRL &= ~CRC_CTL_WIDTH16_START;
  149. if (widthopt == CRC_DATA_WIDTH32)
  150. CRC->CTRL &= ~CRC_CTL_WIDTH32_START;
  151. // sema_give(SEMA_GATE_CRC);
  152. return result;
  153. }
  154. static u32 crc_align(const void *buf, u32 len, u32 init, CrcPoly polyopt, int hardaccel)
  155. {
  156. const u32 *buf32;
  157. const u8 *buf8;
  158. u32 leftsize = len;
  159. u32 size;
  160. u32 align;
  161. u32 crc = init;
  162. crc_algo algo;
  163. if (hardaccel)
  164. algo = CRC_Calc;
  165. else
  166. algo = crc_soft;
  167. align = (u32)buf & 3;
  168. size = 4 - align;
  169. size = size > leftsize ? leftsize : size;
  170. if (align) {
  171. crc = algo(buf, size, init, polyopt, CRC_DATA_WIDTH8);
  172. leftsize -= size;
  173. buf32 = (u32*)((u8*)buf + size);
  174. } else {
  175. buf32 = (u32*)buf;
  176. }
  177. if (leftsize == 0)
  178. return crc;
  179. align = leftsize & 3;
  180. size = leftsize & ~3;
  181. if (size)
  182. crc = algo(buf32, size, crc, polyopt, CRC_DATA_WIDTH32);
  183. buf8 = (u8*)buf32 + size;
  184. if (align)
  185. crc = algo(buf8, align, crc, polyopt, CRC_DATA_WIDTH8);
  186. return crc;
  187. }
  188. u32 xcrc32(const void *buf, u32 len, u32 init, CrcSel hardaccel)
  189. {
  190. return crc_align(buf, len, init, CRC_POLY32, hardaccel);
  191. }
  192. u16 xcrc16(const void *buf, u32 len, u32 init, CrcSel hardaccel)
  193. {
  194. return crc_align(buf, len, init, CRC_POLY16, hardaccel) & 0xffff;
  195. }
  196. u16 xcrc8(const void *buf, u32 len, u32 init, CrcSel hardaccel)
  197. {
  198. return crc_align(buf, len, init, CRC_POLY8, hardaccel) & 0xff;
  199. }