阅读:1903回复:14
谁解决了这个问题,不惜高分(80分)相谢!!!
我的D12固件在枚举过程时使用bushound可以监视到:电脑已经读取了设备描述符、读取了配置描述符(当然前面电脑已经经历了第一次读取设备描述符、地址分配);然后就再也没监视到什么了!
但是我通过程序调试发现:电脑在读取了设备描述符、读取了配置描述符后,其实固件还运行到了读取描述符集合的地方,然后就没有再往下运行了! 因此如果从bushound的监视数据来看:枚举过程还差读取描述符集合、设置配置两步!但如果从程序调试的结果看:固件已经发送了描述符集合,枚举过程就还差设置配置这一步了! 所以问题是:1.不知为什么会有这种矛盾??? 2.反正枚举是没成功,还差几步,那位大侠能解释为什么枚举进行到一半就停了??? |
|
沙发#
发布于:2004-03-24 14:47
关注!我也在做这方面的
|
|
板凳#
发布于:2004-03-24 19:22
仔细检查你的断点0的上传函数,因为上传你所说的描述符集需要超过MaxPacketSize的数据量,也就是说,要分多个包传送。是否发生了数据重叠:上一个包还未完成,后一个包数据覆盖过来;或者通信中断:后续的包没有正常发出。
关注!!! |
|
|
地板#
发布于:2004-03-24 21:15
我的固件中描述符集一共是46字节(一个配置描述符9字节+一个接口描述符9字节+四个端点描述符28字节);调试时我发现:固件一共发送了3次,前两次分别是16字节,最后一次是14字节。但是bushound中就是监视不到这些,发送完了3次后枚举也就中断了!真是奇怪!!!
|
|
地下室#
发布于:2004-03-24 22:45
我的固件中描述符集一共是46字节(一个配置描述符9字节+一个接口描述符9字节+四个端点描述符28字节);调试时我发现:固件一共发送了3次,前两次分别是16字节,最后一次是14字节。但是bushound中就是监视不到这些,发送完了3次后枚举也就中断了!真是奇怪!!! 你的大批数据发送函数是怎么写的? 能否贴出来?是用D12吗?还是什么别的片子? |
|
|
5楼#
发布于:2004-03-24 23:22
我用的是D12,使用的是PHILIP提供的固件,我认为主要有两个函数:
1.获得描述符响应函数 void get_descriptor(void) { unsigned char bDescriptor = MSB(ControlData.DeviceRequest.wValue); if (bDescriptor == USB_DEVICE_DESCRIPTOR_TYPE) {// code_transmit((unsigned char code *)&DeviceDescr, sizeof(USB_DEVICE_DESCRIPTOR)); } else if (bDescriptor == USB_CONFIGURATION_DESCRIPTOR_TYPE) { if(ControlData.DeviceRequest.wLength>CONFIG_DESCRIPTOR_LENGTH) { ControlData.DeviceRequest.wLength=CONFIG_DESCRIPTOR_LENGTH; } code_transmit((unsigned char code *)&ConfigDescr, ControlData.DeviceRequest.wLength); } else stall_ep0(); } 2.断点0发送中断响应 void ep0_txdone(void) { short i = ControlData.wLength - ControlData.wCount; D12_ReadLastTransactionStatus(1); // if (bEPPflags.bits.control_state != USB_TRANSMIT) return;// if( i >= EP0_PACKET_SIZE) { // D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount); ControlData.wCount += EP0_PACKET_SIZE; bEPPflags.bits.control_state = USB_TRANSMIT; } else if( i != 0) { // D12_WriteEndpoint(1, i, ControlData.pData + ControlData.wCount); ControlData.wCount += i; bEPPflags.bits.control_state = USB_IDLE; } else if (i == 0){ D12_WriteEndpoint(1, 0, 0); // bEPPflags.bits.control_state = USB_IDLE; } } void code_transmit(unsigned char code * pRomData, unsigned short len) { ControlData.wCount = 0; if(ControlData.wLength > len) ControlData.wLength = len; ControlData.pData = pRomData; if( ControlData.wLength >= EP0_PACKET_SIZE) { D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData);// ControlData.wCount += EP0_PACKET_SIZE; DISABLE; bEPPflags.bits.control_state = USB_TRANSMIT; ENABLE; } else { D12_WriteEndpoint(1, ControlData.wLength, pRomData);// ControlData.wCount += ControlData.wLength; DISABLE; bEPPflags.bits.control_state = USB_IDLE; ENABLE; } } |
|
6楼#
发布于:2004-03-25 10:44
关于 void ep0_txdone(void)这个函数,
if (bEPPflags.bits.control_state != USB_TRANSMIT) return;// 为什么是不处于USB_TRANSMIT就返回呢? bEPPflags.bits.control_state应该是控制寄存器吧? 关于这个寄存器的这个位你能否把资料贴上来? 个人认为这个逻辑有问题。 [编辑 - 3/25/04 by windyguy] |
|
7楼#
发布于:2004-03-25 11:39
我认为:
if (bEPPflags.bits.control_state != USB_TRANSMIT) return;// 没有问题,其实响应void ep0_txdone(void)这个函数是在D12把端点缓冲区的数据发送完以后,因此再函数中首先判断bEPPflags.bits.control_state ,如果bEPPflags.bits.control_state != USB_TRANSMIT就说明单片机中的数据已经发送完了,所以可以退出这个函数,否则将继续发送余下的数据! 几天了!调试都没进展,问题到底出在那呢????????? |
|
8楼#
发布于:2004-03-25 11:53
1、我们的问题是不是一样?bushound已经读取的设备描述符、配置描述符、接下来应该继续读46字节数据但主机却发了总线复位命令,不知道为什么?郁闷ing....
2、btw:调试环境arm+d12,用multi ice调试已成功读取了46字节内容,并顺利安装了驱动,但烧入片子里就出现问题1 |
|
9楼#
发布于:2004-03-25 13:22
假设“if (bEPPflags.bits.control_state != USB_TRANSMIT)”没有问题,那么之后的代码必然是在“bEPPflags.bits.control_state == USB_TRANSMIT”的情况下才会执行,这样的话“bEPPflags.bits.control_state = USB_TRANSMIT;”这个赋值有什么意义?难道是“D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount);”这个函数调用中把该值改变了?!
我认为: |
|
10楼#
发布于:2004-03-25 13:26
void ep0_txdone(void)
{ short i = ControlData.wLength - ControlData.wCount; D12_ReadLastTransactionStatus(1); // if (bEPPflags.bits.control_state != USB_TRANSMIT) return;//只可能在状态是USB_TRANSMIT的情况下才执行后面的代码! if( i >= EP0_PACKET_SIZE) { D12_WriteEndpoint(1, EP0_PACKET_SIZE, ControlData.pData + ControlData.wCount); ControlData.wCount += EP0_PACKET_SIZE; //下面的赋值是有必要的么?因为状态是USB_TRANSMIT才可能执行到这里,除非上面的 //D12_WriteEndpoint()函数中改变了bEPPflags.bits.control_state为不等于USB_TRANSMIT bEPPflags.bits.control_state = USB_TRANSMIT; } else if( i != 0) { // D12_WriteEndpoint(1, i, ControlData.pData + ControlData.wCount); ControlData.wCount += i; bEPPflags.bits.control_state = USB_IDLE; } else if (i == 0){ D12_WriteEndpoint(1, 0, 0); // bEPPflags.bits.control_state = USB_IDLE; } } [编辑 - 3/25/04 by windyguy] |
|
11楼#
发布于:2004-03-25 13:37
我觉得,首先你的void get_descriptor(void)中不需要
if(ControlData.DeviceRequest.wLength>CONFIG_DESCRIPTOR_LENGTH) { ControlData.DeviceRequest.wLength=CONFIG_DESCRIPTOR_LENGTH; } 这样的截断ControlData.DeviceRequest.wLength的代码,而是直接写成: code_transmit((unsigned char code *)&ConfigDescr, CONFIG_DESCRIPTOR_LENGTH); 事实上的截断工作已经由code_transmit函数中的: if(ControlData.wLength > len) ControlData.wLength = len; 完成了。 当然,你的写法未必会引起错误。但如果你的ep0_rxdone(这个函数你没有贴出)中没有类似如下代码的话: ControlData.DeviceRequest.wValue = SWAP(ControlData.DeviceRequest.wValue); ControlData.DeviceRequest.wIndex = SWAP(ControlData.DeviceRequest.wIndex); ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength); //对控制端点的输入/输出进行应答 D12_AcknowledgeEndpoint(0); D12_AcknowledgeEndpoint(1); ControlData.wLength = ControlData.DeviceRequest.wLength; ControlData.wCount = 0; 尤其是倒数第二句,那么就应该会出问题!!! 不介意的话,可以把ISR和Chap9两个文件发到我的邮箱里。 |
|
|
12楼#
发布于:2004-03-25 16:00
zmwk!你需要的文件已经发到你的信箱了!非常感谢你的热心帮忙!当然还要感谢其他网友的热心参与!其实我的ep0_rxdone()函数就是那样写的!
|
|
13楼#
发布于:2004-03-25 16:38
为了感谢zmwk兄弟的热心帮忙,先奉上20分以资鼓励!!!
|
|
14楼#
发布于:2004-03-25 17:21
我已经回你的EMail了。
试用我的固件看看是不是硬件故障? 先排除了硬件问题再说! |
|
|