USB crc5计算

CRC 的发生和校检,发生器和检验器里的移位寄存器置成为全 1型。对于每个被发送或者被收到的数据位,当前余项的最高一位和数据位进行异或( XOR ),然后,余项是左移 1 位,并且,最低一位置零。如果异或的结果是 1 ,余项和生成多项式作异或。当检查的字段最后的一位被发送的时候,对发生器里的 CRC取反,再以最高位( MSb )在前发给检验器。

crc5的生成多项式为x5+x2+1;表示为5’b00101(x5不需表示出来)
这里写图片描述

对于每一位数据D有:
R0<=R4 ^ D
R1<=R0;
R2 <= (R4 ^ D) ^ R1;
R3 <= R2;
R4 <= R3;
数据流D是从LSB开始,对于token pid则依次处理ADR[0],ADR[1],……ADR[7],ENDP[0],……最后ENDP[3]。

(1)按bit串行计算,用testbench表现为:

bit[4:0] crc_reg,crc_reg_pre;
bits[7:0] token_bits;
bits[10:0] data_bits;
bits[4:0] crc_send;
bit[23:0] bitstream_send;
initial begin
	crc_reg = 5’h1f;
	token_bits = 8’b0110_1001; // IN token, {~pid[3:0],pid[3:0]}=0110_1001
	data_bits = 19’b0001_0001000  // (黄色为ENDP[3:0]=0001,绿色为ADDR[7:0]=0001000)
 	for(int i=0;i<11;i++) begin
		crc_reg_pre = crc_reg;
		crc_reg[0] = data_bits[i] ^ crc_reg_pre[4];
		crc_reg[1] = crc_reg_pre[0];
		crc_reg[2]= crc_reg_pre[1] ^ bitdata[i] ^ crc_reg_pre[4];
		crc_reg[3] = crc_reg_pre[2];
		crc_reg[4] = crc_reg_pre[3];
	end
	crc_send = ~ {crc_reg[0], crc_reg[1], crc_reg[2], crc_reg[3], crc_reg[4]}; //取反,MSB在前
end

运算结果crc_reg=10100
bitstream_send = {crc_send,data_bits,token_bits}
在DP/DM线上是先发bitstream_send[0],最后发bitstream_send[23]。
在接收端是对{crc_send,data_bits}进行同样的crc计算,计算结果为01100(接收正确的crc计算结果都应为01100)
(2)并行计算
初始值:R0=R1=R2=R3=R4=1;
对每一比特的串行计算为:R0<=R4 ^ D; R1<=R; R2 <= (R4 ^ D) ^ R1;R3 <= R2; R4 <= R3;
则有:
这里写图片描述
最终得并行计算的公式为:
R0=1D0D1D4D5^D10
R1=1D0D3D4D6^D9
R2=1D0D1D2D3D4D7D8D10
R3= D0D1D2D3D6D7D9
R4=1D0D1D2D5D6D8
(3)按byte计算

bit[7:0] crc_reg,crc_poly;
bits[7:0] token_bits;
bits[10:0] data_bits;
bits[4:0] crc_send;
bit[23:0] bitstream_send;
initial begin
	crc_reg = 8’b0001_1111; //这里的[0]对应方法(1)的[4],对应R4
	crc_poly = 8’b00010100; //(对多项式’h5进行msb~lsb反置后右移3,即[0]对应R4位置
	token_bits = 8’b0110_1001; // IN token, {~pid[3:0],pid[3:0]}=0110_1001
	data_bits = 19’b0001_0001000  // (黄色为ENDP[3:0]=0001,绿色为ADDR[7:0]=0001000)
 	for(int i=0;i<2;i++) begin
	crc_reg = data_bits[7:0] ^ crc_reg;
	for(int j=0;j<8;j++) begin
			if(crc_reg[0]==1) begin
				crc_reg = {1’b0,crc_reg[7:1]};
				crc_reg = crc_reg ^ crc_poly;
			end
			else begin
				crc_reg = {1’b0,crc_reg[7:1]};
			end
			if((i==1) && (j==2))
				break;
		end
	end
	crc_send[4:0] = crc_reg[4:0] ^ 5’h1f; //不用高低位反置,因为[0]表示的是R4了
end

参考:
https://wenku.baidu.com/view/1ae311b3aef8941ea66e0535.html###

https://wenku.baidu.com/view/1a80b6601ed9ad51f01df2b8.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CRC(Cyclic Redundancy Check,循环冗余校验)是一种常用的错误检测算法,特别是在USB(Universal Serial Bus)这样的串行通信中,为了确保数据传输的准确性。Java CRC16USB通常指的是使用16位CRC算法,特别适用于USB设备的数据传输,因为USB规范支持这种简单的校验。 CRC16USB算法的工作原理是将输入数据块通过一系列固定的逻辑运算,生成一个16位的校验码。在发送数据时,会附加这个校验码,接收端再计算接收到的数据的CRC值并与发送端的校验码进行比较,如果两者匹配,则认为数据传输正确,否则可能存在错误。 具体实现步骤可能包括: 1. 初始化一个16位的CRC寄存器为预定义的CRC初始值。 2. 将输入数据逐字节处理,对于每个字节进行CRC计算,通常涉及异或(XOR)和位移(Shift)操作。 3. 当所有数据处理完毕后,从CRC寄存器获取生成的16位校验码。 如果你想要深入了解Java中如何使用CRC16USB,你可能会关注以下几个方面: - 如何在Java代码中利用`java.util.zip.CRC32`或者其他第三方库来实现CRC16USB计算。 - USB协议中哪些部分涉及CRC校验,比如数据包的结构。 - 如何在USB设备驱动或应用层中集成CRC16USB验证。 相关问题: 1. Java中有哪些内置或第三方库支持CRC16USB计算? 2. USB通信中的数据帧结构中如何包含CRC16USB校验? 3. 如果在实际项目中遇到CRC校验失败,应如何调试和修复?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值