USB IP核FPGA调试
Posted yuanyun_elber
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USB IP核FPGA调试相关的知识,希望对你有一定的参考价值。
上次说到我们的USB发送会多一个字节的问题,原因其实没有调查清楚。但是一条道走不通的话就换一条道嘛,UTMI接口有8bit单向和16bit双向模式的区别,我们之前使用的是8bit单向模式,抱着试试看的心理,硬件同事又改了一个UTMI 16bit的版本(我司另外一个项目了解下来也是16bit接口),果然没有这个多发一个字节的毛病了。
改成16bit utmi后,软件方面需要改一个usb2phycfg,一开始utmi clock还是60Mhz,不是30Mhz的,不对。
后来查了一下,usb2phycfg配置得在softreset之前进行,这个寄存器主要就是配UTMI接口的,不过UTMI接口也可以通过phy子板上的跳线来跳,只不过这一版还是通过软件来配的。
但是full speed的交互有问题,这个先不管,优先级低一些。
而high speed可以交互几个transfer了,包括get device descriptor,set address,但是跑到get config descriptor这条之后,Host很快就发reset信号了,应该是数据不太对
下图是fullspeed,后面的in一直nack,打印很多1 orphaned之类的信息,full speed很不正常
而highspeed下,会多几条信息交互,但是后面就会reset
查看了一下,应该是因为get config descriptor的数据有点问题
单步调试
memcpy(buf, &hs_config_desc, sizeof(hs_config_desc));
数据没有完全复制过去
hs_config_desc
而buf中
会发现4个字节没有复制过来,这个应该和controller访问0x23000这个64位区域有关
做一些实验:
uint8_t* p_8;
uint32_t* p_32;
p_8 = (uint8_t*)0x23000;//这个地址可以写
*p_8 = 0x55;
p_8 = (uint8_t*)0x23004;//这个地址不可以写
*p_8 = 0x55;
p_32 = (uint32_t*)0x23000;//这个地址可以写
*p_32 = 0x12345678;
p_32 = (uint32_t*)0x23004;//这个地址可以写
*p_32 = 0x12345678;
p_8 = (uint8_t*)0x2000c000;//这个地址可以写
*p_8 = 0x55;
p_8 = (uint8_t*)0x2000c004;//这个地址可以写
*p_8 = 0x55;
问题就聚焦于8位地址赋值和32位地址赋值有什么区别上了,我们看了一下,
32位地址赋值是如下汇编代码:
0x20006740 9A01 LDR r2,[sp,#0x04]
0x20006742 F2456078 MOVW r0,#0x5678
0x20006746 F2C12034 MOVT r0,#0x1234
0x2000674A 6010 STR r0,[r2,#0x00]
而8位地址赋值,则是如下汇编代码
这个STRB查了一下
3、STRB
STRB指令首先数据总线(整个字的四个字节)都填充上要写入的一个字节的数据。然后,外部存储系统激活合适的字节存储子系统去存储这一个字节的数据。
“外部存储系统激活合适的字节存储子系统去存储这一个字节的数据”这句话,我是这样理解的,以"strb r3,[r4]"为例进行说明。
假设r3 = 0x12 ,r4 = 0x30000001
STRB指令首先数据总线上都填充上要写入的一个字节的数据,也就是数据总线为0x12121212,访问的字地址是0x30000000。因为要存储一个字节的数据到0x30000001,而0x30000000这个字的其他单元不能更改,所以就将DQM0、DQM2、DQM3都有效,而不屏蔽DQM。这样在写入的过程中,只将0x12写入到0x30000001单元中,而其他三个单元不修改,从而完成strb指令规定的任务。
看来,这个问题需要硬件同事跟进一下了。
以上是关于USB IP核FPGA调试的主要内容,如果未能解决你的问题,请参考以下文章