阅读:2921回复:25
再讨论枚举问题,这次有1000分,已结贴!
我做的是isp1581,mcu用的是dsp。前不久刚把isp1581+tms320f206调好,可是一样的固件拿到isp1581+tms320vc5402和isp1581+adsp-21062(sharc)的两块板子上就只能收到第一个描述符80 06 00 01 00 00 40 00,返回了数据有就什么也没有了,收不到下一个set address请求。
以前做的时候也曾经遇到这个问题,可是搞了几周后有一天突然就好了,始终没找到原因,因此这次来时还是束手无策呀! [编辑 - 2/11/04 by jinghuiren] |
|
最新喜欢:![]() |
沙发#
发布于:2003-05-24 01:04
void Chap9_ClearFeature(void)
{ unsigned char endp; unsigned char bRecipient = ControlData.DeviceRequest.bmRequestType & USB_RECIPIENT; unsigned short wFeature = ControlData.DeviceRequest.wValue; unsigned short wEPCFG; unsigned char dir = ControlData.DeviceRequest.bmRequestType & SB_REQUEST_DIR_MASK; if(dir) Chap9_StallEP0InControlRead(); if( ControlData.DeviceRequest.wLength == 0 ) { switch(bRecipient) { case USB_RECIPIENT_DEVICE: //.... case USB_RECIPIENT_ENDPOINT: if( ControlData.DeviceRequest.wIndex & USB_ENDPOINT_DIRECTION_MASK) endp = (ControlData.DeviceRequest.wIndex*2 + 1); else endp = (ControlData.DeviceRequest.wIndex*2); if(wFeature == USB_FEATURE_ENDPOINT_STALL) { // Clear the data toggle bit to (set to 0) and clear buffers before clear stall of // the endpoint. wEPCFG = ISP1581_GetEndpointConfig(endp); ISP1581_SetEndpointConfig(endp, 0); // disable endpoint * // Enable endpoint, clear the buffer and set the data toggle bit to 0. ISP1581_SetEndpointConfig(endp, wEPCFG); ISP1581_SetEndpointStatus(endp, 0); // clear the Stall condition of the Chap9_ControlWriteHandshake(); } else { Chap9_StallEP0InControlWrite(); } break; default: Chap9_StallEP0InControlWrite(); break; } } else { Chap9_StallEP0InControlWrite(); } } |
|
板凳#
发布于:2003-05-24 01:09
ISP1581 停止处理
停止功能 批量或中断端点支持停止特性的设定和清除即STALL 功能停止的端点将一直保持STALL 状态直至主机通过控制管道发布一个清除停止特性命令如果端点的停止特性被解除UNSTALL , 它将清除缓冲区双缓冲区并使数据触发位复位成0 PID DATA0 在UNSTALL 后的第一次数据交易中ISP1581接收带有PID DATA0 的数据包给一个OUT 令牌并发送一个带有PID DATA0 的数据包给一个IN 令牌. 停止中断 若端点被配置成单独ACK 模式停止状况发生时没有对应的中断产生因为端点的停止不会对固件产生任何影响只需要主机发布一个CLEAR_FEATRUE 请求就可将停止状况解除.在调试模式下就能够产生中断但是这个中断并没有用来提醒用户现在正在处理的是停止中断的标识只有通过在该停止端点没有任何数据交易之前固件也没有进行其它数据的处理而且也不处于空闲等待的情况来判定此时正在处理该中断端点后来所接收的封包会将以前的信息覆盖, 端点的停止和退出停止状态 停止一个端点可以随时被停止通过设置端点状态寄存器的STALL 位或主机向端点发送设定端点停止特性的请求两种方式都可将端点设定成停止状态 例ISP1581_SetEndpointStatus(bEPIndex, epctlfc_stall); 停止功能优先级最高因此即使同时有IN 端点缓冲区出现数据或OUT 端点为空的情况主机也不理会而去接收端点停止退出清除将端点的STALL 位清除另外若缓冲区中还有数据就要先将端点禁止再让端点使能来清除缓冲区 . |
|
地板#
发布于:2003-05-24 10:20
如果你的固件已经是调好的,只是换了平台后不能进行!一般是由于平台硬件的差异造成的,从你的现象分析,函数能执行,中断也能进入,只是不能正常进行,说明是中断处理有问题,一是硬件电路中检查5402的中断与ISP1581的中断是否匹配,5402是低脉冲触发有效,因此就要保证ISP1581给出的中断符合5402的触发条件。二是软件处理,中断信号产生,ISR响应后,中断能否回到原初始条件,以便能再次产生中断,你的现象就是只进一次中断,之后就不产生了。很可能就是这个原因,不同的硬件平台中断的触发条件、响应都有可能有差别的。仔细找一下!
|
|
|
地下室#
发布于:2003-05-24 12:35
首先感谢两位的回答,在收到get descriptor中断之前还收到两次中断,一次是复位,一次是高速状态检测,我看了5402的中断屏蔽寄存器和中断标志寄存器的值,没有问题的,另外收到get descriptor的setup包的同时,1581还返回了ack给主机,因此还有一个是ep0tx中断,当我想端点0tx写入描述符内容并使能后,就再没有中断来了,此时我发现中断屏蔽寄存器与1581有关的那一位是使能的,也就说只要有中断一定能产生的!
|
|
5楼#
发布于:2003-05-24 13:15
cakor兄,能否把你的相关函数贴出来让我参考一下呀,下面是我的get descriptor函数以及相关的内容:
void Chap9_GetDescriptor(void) { unsigned char bDescriptor; bDescriptor= MSB(SUD[1]); if(!(SUD[0]&0x80))//如果不是getdescriptor就stall端点0 Chap9_StallEP0InControlWrite(); switch(bDescriptor) { case USB_DEVICE_DESCRIPTOR_TYPE://如果是获得设备描述符 { if(Isp1581Flag.ConnectSpeed == HighSpeed)//如果是高速 Chap9_BurstTransmitEP0((unsigned short*)DeviceDescr_H, 9);//发送高速描述符给主机 else//否则发送全速描述符 Chap9_BurstTransmitEP0((unsigned short*)DeviceDescr, 9); break; } case USB_CONFIGURATION_DESCRIPTOR_TYPE://如果是获得配置描述符则返回配置描述符给主机 { if(Isp1581Flag.ConnectSpeed == HighSpeed) Chap9_BurstTransmitEP0((unsigned short*)ConfigDescr_H, 23); else Chap9_BurstTransmitEP0((unsigned short*)&ConfigDescr, 23); break; } default: Chap9_StallEP0InControlRead(); break; } } void Chap9_BurstTransmitEP0(unsigned short* buf, unsigned short len) { unsigned char i = 0; rega_epindex=0x01;//写端点索引寄存器,选择端点0tx if(SUD[3] == 9)//如果SETUP数据的WLENGTH也就是获得配置描述符(9),这是唯一的描述符字节数为奇数的情况,因此单独处理 { rega_dcount = 0x09;//写缓冲区长度寄存器(1CH),用来跟踪写入的数据数量 for(i=0; i<len; i++) { rega_dport = *buf;//往数据端口寄存器(20H)写入数据 buf++; } } else//对于其他情况或的设备描述符就在这里处理 { rega_dcount = (2*len);//len传过来的数据长度是以字为单位的,因此要乘2才是字节 for(i=0; i<len; i++) { rega_dport = *buf;//写数据到数据端口 buf++; } } Isp1581Flag.EP0_state = USB_CONTROLREADHANDSHAKE; //设点状态阶段状态标志,这个标志会引起ep0tx中断中向主机发送空数据包来完成状态阶段 //下面是ep0tx中处理状态阶段的部分: //case USB_CONTROLREADHANDSHAKE: //ISP1581_SetEndpointStatus(0x01, 0x02);//向主机发送空数据包 //Isp1581Flag.EP0_state = USB_CONTROLREADHANDSHAKE; //break; } 我用的是highspeed,因为用的是16位的数据线,因此要把描述符给拼起来,否则会无法通过,这在我之前的那块板子上我已经验证过了的,描述符肯定没问题。 下面是描述符: unsigned short DeviceDescr_H[] = { 0x0112,//描述符长度与类型 0x0200,//bcdUSB,因为这个搞好是2字节的,因此不用处理 0x0000,//class与subclass 0x4000,//端点0最大包大小64与protocol 0 0x0547,//vid,此时应该还与vid和pid无关 0x1b49,//pid 0x0000,//bcddevice,版本号 0x0000,//厂商和产品描述符索引 0x0100//配置个数与序列号 }; 描述符拼接的规则,按照usb数据的发送规则,先发低字节后发高字节,因此放在低字节的8位应该赋给描述符结构里的前一个元素,比如第一个0x0112,主机收到后会把12h给结构的第一个元素bLength,把01h给第二个元素bDescriptorType |
|
6楼#
发布于:2003-05-24 17:44
jinghuiren兄,我觉得是你的硬件的问题,当然你最好先检查一下编译器的规则,比如中断响应,数据类型等等。在枚举的开始,你可以用bushound看到数据的收发的!
|
|
7楼#
发布于:2003-05-24 21:56
这块板子和已经调通的那块板子唯一的区别就是供电问题,调通的那个用的是5v板上供电,而现在这块是3.3v板上供电,但是电源的连接方法是按照datasheet给的连接的呀,而且datasheet明确说明1581这两种供电方式都是可以的。
我在前面已经提到,我收到的中断里有一个是ep0tx中断,这个中断的产生原因我认为是收到了get descriptor的setup包,1581给主机产生ack信号因而产生的中断,这说明缺省的地址0已经正常工作,我用bushound检测不到数据,因此很有可能是数据没有发给主机,但是我检查了发送程序,在那块调通的板子上是完全可行的,确实是没有问题的呀,真是奇怪,这几天老板还整天催我,哎,这日子没法过了! :( |
|
8楼#
发布于:2003-05-24 23:12
不好意思,jinghuiren老兄,我是那个问你pipe 问题的菜鸟,感谢你的帮助。
我对那个问题还有个新的想法,麻烦你再去看看 谢谢! ;) |
|
9楼#
发布于:2003-05-25 12:58
jinghuiren兄,我建议你到:
http://www.usb.org/developers/compliance/DeviceHSTestforAgilent.pdf 去看看他的TEST对你有没有帮助吧!! |
|
10楼#
发布于:2003-05-25 13:02
还有这里!
http://www.usb.org/developers/docs/Device_HS_test_tektronix41503.pdf 但是这些仪器都很贵的,买不起的 |
|
11楼#
发布于:2003-05-25 13:19
jinghuiren,兄台!希望这些也对你有用!
USB 2.0 测试步骤可从以下URL下载: www.usb.org/developers/doc.html 1. Universal Serial Bus Implementers Forum Full and Low-Speed Compliance Test Procedure 2. Universal Serial Bus Implementers Forum High-Speed Electrical Test Procedure USB 2.0 Test Tool可从以下URL下载: www.usb.org/developers/tools.html 1. USBCV 2. USBCheck 3. USB High-speed Electrical Test Tool Kit |
|
12楼#
发布于:2003-05-25 13:43
老兄,多谢你的建议了,我刚才看了一下,我们这里没有那么好的仪器呀,哎,我们这只有好一点的数字示波器,不过已经试过了,根本检测不到总线上设备发给主机的数据。
|
|
13楼#
发布于:2003-05-25 13:46
对了cakor兄,你是否也是做isp1581的,那么能否把你相关的处理函数发一份给我让我参考一下呢,我只需要与get_device_descriptor有关的部分,就如我之前贴出来的那段程序一样,我想比较一下有何不同,看是否我还有什么东西漏掉了!
多谢了。 我的信箱:jinghuiren@163.com [编辑 - 5/25/03 by jinghuiren] |
|
14楼#
发布于:2003-05-25 14:25
误会,误会!我现在只是做D12的。做什么都无所谓,思路大概是一样的吧
|
|
15楼#
发布于:2003-05-26 02:07
在刚开始枚举的阶段,就是收到0x80,,,,0x40的时候,这时的地址还是为0,所以bushound一定可以看到,你回送8个字节的描述符后,就应该收到,set address,一要直到set config之后才看不到ep0的数据了,我觉得你看一下你的器件手册,是否在发送完成之后,还会产生一个中断,这个中断你要直接清除掉,另外你要看一下,usb总线的上的电阻接法,再有我记得好像5v和3v的器件的设置不一样的!还有就是,如果用3v,那么可能你的dsp也要用3v!
|
|
16楼#
发布于:2003-05-26 07:59
老弟!还没有搞定啊!我也觉得你的硬件有可能有时序或是别的什么问题。不行,我帮你看看你的电路,5402还算熟悉,也在上面开发过USB1.1。1581的硬件也不是很复杂,支持3V系列。如果硬件没有什么问题,再集中经历搞定固件部分。固件的焦点在于:第一,数据发出去没有,第二,接收的中断清掉没有,能否再收中断。确定了这两部分,也就没问题了!
|
|
|
17楼#
发布于:2003-05-26 12:53
首先写写newtech和yalong两位老兄的回复,我现在也开始怀疑是否是硬件问题了,因为以前只完成过5v器件的工作,所以不至3.3v是否能行,可是现在板子已经做好了,要改动比较麻烦
固件我已经仔细检查过了,应该是没有问题的,因为在5v供电的一块板子上已经通过了的!(相关的段落我已经在上面的回复贴子里贴出来了) 我的情况是:用bushound监测不到数据,这说明数据很有可能是没有发送,可是在固件中当我把数据写完后已经强制使该端点生效了,也就是说只要收到in令牌,数据一定会发走的。 在完成发送工作后就在没有收到中断了,只是在收到setup包的时候同时收到了一个ep0tx的中断,我认为这个中断是设备因为正确收到setup包而给主机发送ack信号而产生的。 我想请yalong兄给我看一下电路,如果是硬件的问题我就只好飞线了! |
|
18楼#
发布于:2003-05-26 14:44
如果方便也发一份给我我帮你看看!
|
|
19楼#
发布于:2003-05-27 10:29
那位仁兄还有好的建议吗?
|
|
上一页
下一页