找回密码
 立即注册
查看: 150|回复: 6

请教USB传输中CRC5的计算问题,谢谢

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-05-01 19:17:52
已绑定手机

19

主题

208

回帖

492

积分

中级会员

积分
492
发表于 2025-3-27 17:37:41 | 显示全部楼层 |阅读模式
我始终不能使用 在线-ip33 中的计算工具,将图中的给出的传输包中的CRC5计算正确

图中: ADDR=2,ENDP=0,那在在线-ip33 中, 选择CRC计算类型是 CRC-5/USB,
现在7位ADDR 和 4位ENDP,低位在前的位数据排列为  0100 000 0000,
请问我填写CRC计算的数据是 0x40 0x00 吗?  得到CRC5的计算结果是 0x18,
和图片中的 crc5=0x15 不同. 请问该如何计算呢? 谢谢

截图202503271730047414.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-05-01 19:17:52
已绑定手机

19

主题

208

回帖

492

积分

中级会员

积分
492
发表于 2025-3-27 17:40:21 | 显示全部楼层
而数据传输包中的CRC16, 直接按照实例数据,使用 在线-ip33 的CRC-16/USB计算工具, 计算出来的结果和实例的CRC16数据是一致的!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-05-01 19:17:52
已绑定手机

19

主题

208

回帖

492

积分

中级会员

积分
492
发表于 2025-3-27 17:41:00 | 显示全部楼层
CRC5存在数据的补位问题,不知道如何处理?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-3-27 21:03:06 | 显示全部楼层


搜刮了下github,找到两个比较权威的仓库有crc5函数,其中CRC5_MSBfirst计算结果和图中一致可以参考下

opentitan/hw/dv/dpi/usbdpi/usb_crc.c at master · lowRISC/opentitan
wireshark/wsutil/crc5.c at master · wireshark/wireshark

截图202503272102137082.jpg
截图202503272102328080.jpg

示例代码:
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #define INT_SIZE 32  // Assumes 32-bit integer size
  4. uint32_t CRC5_MSBfirst(uint32_t dwInput, int iBitcnt) {
  5.   const uint32_t poly5 = (0x05 << (INT_SIZE - 5));
  6.   uint32_t crc5 = (0x1f << (INT_SIZE - 5));
  7.   uint32_t udata = (dwInput << (INT_SIZE - iBitcnt));
  8.   if ((iBitcnt < 1) || (iBitcnt > INT_SIZE)) {  // Validate iBitcnt
  9.     return 0xffffffff;
  10.   }
  11.   while (iBitcnt--) {
  12.     if ((udata ^ crc5) & (0x1 << (INT_SIZE - 1))) {  // bit4 != bit4?
  13.       crc5 <<= 1;
  14.       crc5 ^= poly5;
  15.     } else {
  16.       crc5 <<= 1;
  17.     }
  18.     udata <<= 1;
  19.   }
  20.   // Shift back into position
  21.   crc5 >>= (INT_SIZE - 5);
  22.   // Invert contents to generate crc field
  23.   crc5 ^= 0x1f;
  24.   return crc5;
  25. }  // CRC5()
  26. /* This is the little endian version, so you can feed an 11 bit data
  27. * value and get back 5 bits to OR in to the top to construct 16 bits
  28. *
  29. * Adapted by mdhayter
  30. */
  31. uint32_t CRC5(uint32_t dwInput, int iBitcnt) {
  32.   const uint32_t poly5 = 0x14;
  33.   uint32_t crc5 = 0x1f;
  34.   uint32_t udata = dwInput;
  35.   if ((iBitcnt < 1) || (iBitcnt > INT_SIZE)) {  // Validate iBitcnt
  36.     return 0xffffffff;
  37.   }
  38.   while (iBitcnt--) {
  39.     if ((udata ^ crc5) & 0x01) {
  40.       crc5 >>= 1;
  41.       crc5 ^= poly5;
  42.     } else {
  43.       crc5 >>= 1;
  44.     }
  45.     udata >>= 1;
  46.   }
  47.   // Invert contents to generate crc field
  48.   crc5 ^= 0x1f;
  49.   return crc5;
  50. }  // CRC5()
  51. static uint8_t crc5_usb_bits(uint32_t v, int vl, uint8_t ival)
  52. {
  53.     /* This function is based on code posted by John Sullivan to Wireshark-dev
  54.      * mailing list on Jul 21, 2019.
  55.      *
  56.      * "One of the properties of LFSRs is that a 1 bit in the input toggles a
  57.      *  completely predictable set of register bits *at any point in the
  58.      *  future*. This isn't often useful for most CRC caculations on variable
  59.      *  sized input, as the cost of working out which those bits are vastly
  60.      *  outweighs most other methods."
  61.      *
  62.      * In USB 2.0, the CRC5 is calculated on either 11 or 19 bits inputs,
  63.      * and thus this approach is viable.
  64.      */
  65.     uint8_t rv = ival;
  66.     static const uint8_t bvals[19] = {
  67.         0x1e, 0x15, 0x03, 0x06, 0x0c, 0x18, 0x19, 0x1b,
  68.         0x1f, 0x17, 0x07, 0x0e, 0x1c, 0x11, 0x0b, 0x16,
  69.         0x05, 0x0a, 0x14
  70.     };
  71.     for (int i = 0; i < vl; i++) {
  72.         if (v & (1 << i)) {
  73.             rv ^= bvals[19 - vl + i];
  74.         }
  75.     }
  76.     return rv;
  77. }
  78. uint8_t crc5_usb_11bit_input(uint16_t input)
  79. {
  80.     return crc5_usb_bits(input, 11, 0x02);
  81. }
  82. int main() {
  83.     uint8_t addr = 0x20;
  84.     uint8_t endp = 0;
  85.     uint32_t combined_data = ((uint32_t)addr << 4) | (endp & 0x0F); // 组合 7 位 ADDR 和 4 位 ENDP
  86.     printf("combined_data 结果: 0x%04X\n", combined_data);
  87.     uint8_t result = CRC5_MSBfirst(combined_data,11);
  88.     printf("MSB CRC5 结果: 0x%02X\n", result);
  89.     printf("MSB CRC5 ~结果: 0x%02X\n", (~result) & 0xFF);
  90.      result = CRC5(combined_data,11);
  91.     printf("LSB CRC5 结果: 0x%02X\n", result);
  92.     printf("LSB CRC5 ~结果: 0x%02X\n", (~result) & 0xFF);
  93.     auto x = crc5_usb_11bit_input(combined_data);
  94.     printf("crc5_usb_11bit_input LSB 结果: 0x%02X\n", x);
  95.     return 0;
  96. }
复制代码


三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-05-01 19:17:52
已绑定手机

19

主题

208

回帖

492

积分

中级会员

积分
492
发表于 2025-3-27 21:50:06 | 显示全部楼层
明天我来试试程序计算,非常感谢您的指点!
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:121
  • 最近打卡:2025-05-01 19:17:52
已绑定手机

19

主题

208

回帖

492

积分

中级会员

积分
492
发表于 2025-3-30 18:55:54 | 显示全部楼层
把程序移植到 擎天柱 核心板上,KC251 编译测试了一下, 使用USB已知数据计算了 CRC5, 结果符合样本数据(见 www.usbzh.com 中usb报文)
具体结果描述参见 main.c 中说明;
下面附上整个工程,再次感谢 ercircle 的指点!

CRC5-KC251.zip

218.31 KB, 下载次数: 6

点评

真棒,指点谈不上,一起学习  详情 回复 发表于 2025-3-30 22:58
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:162
  • 最近打卡:2025-05-01 06:56:44
已绑定手机

56

主题

1319

回帖

2938

积分

荣誉版主

无情的代码机器

积分
2938
发表于 2025-3-30 22:58:10 | 显示全部楼层
机灵*** 发表于 2025-3-30 18:55
把程序移植到 擎天柱 核心板上,KC251 编译测试了一下, 使用USB已知数据计算了 CRC5, 结果符合样本数据( ...

真棒,指点谈不上,一起学习
三天不学习,赶不上刘少奇~
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:37 , Processed in 0.226778 second(s), 86 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表