阅读:1351回复:6
SETUP事务后的第一个IN包在何时发送?
为何在SETUP事务后,如果是主机请求数据,第一个包在SETUP后直接发送,以后的包在tx0中发送?为何不是全部的数据都在tx0中发送?
|
|
沙发#
发布于:2005-08-03 13:52
The normal process is:
SETUP--> IN_TOKEN--> Get data from the callback func. then IN_TOKEN--> |
|
板凳#
发布于:2005-08-03 14:01
本来我也是象你这么理解的,但我在看D12的固件源码时,发现好像并不是这样的。
因为代码比较长,而且那个代码网上到处都有,我就不发了。 |
|
地板#
发布于:2005-08-03 14:05
what's tx0????
You can write your own usb codes .... |
|
地下室#
发布于:2005-08-03 14:20
//端点0 OUT 中断
void ep0_rxdone(void) { unsigned char ep_last, i; //清中断标志 ep_last = D12_ReadLastTransactionStatus(0); //接收到SETUP包(一次处理的开始) if (ep_last & D12_SETUPPACKET) { //处理开始时,将下面两个字段清零 ControlData.wLength = 0; ControlData.wCount = 0; //读取SETUP数据,如果SETUP包出错,返回 if( D12_ReadEndpoint(0,sizeof(ControlData.DeviceRequest), (unsigned char *)(&(ControlData.DeviceRequest))) != sizeof(DEVICE_REQUEST) ) { D12_SetEndpointStatus(0, 1); D12_SetEndpointStatus(1, 1); bEPPflags.bits.control_state = USB_IDLE; return; } //数据高低字节交换,因为USB的数据结构与KEIL C51的数据结构不同,所以要高低字节交换 #ifdef __C51__ ControlData.DeviceRequest.wValue = SWAP(ControlData.DeviceRequest.wValue); ControlData.DeviceRequest.wIndex = SWAP(ControlData.DeviceRequest.wIndex); ControlData.DeviceRequest.wLength = SWAP(ControlData.DeviceRequest.wLength); #endif //对控制端点的输入/输出进行应答 D12_AcknowledgeEndpoint(0); D12_AcknowledgeEndpoint(1); //设置接收或发送的初始状态 ControlData.wLength = ControlData.DeviceRequest.wLength; ControlData.wCount = 0; /*如果需要向主机发回数据,则在此设置标志,然后将进入主循环*/ //向主机发回数据 if (ControlData.DeviceRequest.bmRequestType & (unsigned char)USB_ENDPOINT_DIRECTION_MASK) { bEPPflags.bits.setup_packet = 1; bEPPflags.bits.control_state = USB_TRANSMIT; //设置发送状态 } //从主机接收数据 else { //不带数据的请求 if (ControlData.DeviceRequest.wLength == 0) { bEPPflags.bits.setup_packet = 1; bEPPflags.bits.control_state = USB_IDLE; //设置空闲状态 } //带数据的请求 else { if(ControlData.DeviceRequest.wLength > MAX_CONTROLDATA_SIZE) { //长度出错的话,返回空闲状态 bEPPflags.bits.control_state = USB_IDLE; D12_SetEndpointStatus(0, 1); D12_SetEndpointStatus(1, 1); } else { bEPPflags.bits.control_state = USB_RECEIVE; //设置接收状态 } } } } //SETUP后的数据接收状态 else if (bEPPflags.bits.control_state == USB_RECEIVE) { i = D12_ReadEndpoint(0,EP0_PACKET_SIZE, ControlData.dataBuffer + ControlData.wCount); ControlData.wCount += i; if( i != EP0_PACKET_SIZE || ControlData.wCount >= ControlData.wLength) { // 接收完毕 bEPPflags.bits.setup_packet = 1; bEPPflags.bits.control_state = USB_IDLE; //设置空闲状态 } } //进入等待状态 else { bEPPflags.bits.control_state = USB_IDLE; //设置空闲状态 } //debug_send_string_com( "ep0_rxdone() end\n" ); } |
|
5楼#
发布于:2005-08-03 14:23
//主循环
while( TRUE ) { //总线复位处理 if (bEPPflags.bits.bus_reset) { DISABLE; bEPPflags.bits.bus_reset = 0; //清总线复位标志 ENABLE; //debug_send_string_com( "bus_reset\n" ); } //挂起改变处理 if (bEPPflags.bits.suspend) { DISABLE; bEPPflags.bits.suspend = 0; //清挂起改变标志 ENABLE; //debug_send_string_com( "suspend\n" ); } //Setup包处理 if (bEPPflags.bits.setup_packet) { DISABLE; bEPPflags.bits.setup_packet = 0; //清除Setup包标志 ENABLE; //debug_send_string_com( "setup_packet\n" ); //在这里程序将进入请求处理子程序,并发送第一个数据包 control_handler(); //调用请求处理子程序 } } |
|
6楼#
发布于:2005-08-03 14:25
下面的代码将发送其他的数据包
//端点0 IN 中断 void ep0_txdone(void) { short i = ControlData.wLength - ControlData.wCount; //debug_send_string_com( "ep0_txdone() begin\n" ); //清中断标志位 D12_ReadLastTransactionStatus(1); //非发送状态,返回 if (bEPPflags.bits.control_state != USB_TRANSMIT) return; if( i >= EP0_PACKET_SIZE) { //剩下数据大于16B,发送16B 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) { //发送完毕,发送0B D12_WriteEndpoint(1, 0, 0); bEPPflags.bits.control_state = USB_IDLE; } //debug_send_string_com( "ep0_txdone() end\n" ); } |
|