whoIme
驱动牛犊
驱动牛犊
  • 注册日期2004-06-29
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1352回复:6

SETUP事务后的第一个IN包在何时发送?

楼主#
更多 发布于:2005-08-03 09:54
  为何在SETUP事务后,如果是主机请求数据,第一个包在SETUP后直接发送,以后的包在tx0中发送?为何不是全部的数据都在tx0中发送?
whoIme
驱动牛犊
驱动牛犊
  • 注册日期2004-06-29
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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" );
}
whoIme
驱动牛犊
驱动牛犊
  • 注册日期2004-06-29
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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();                  //调用请求处理子程序
        }
    }
whoIme
驱动牛犊
驱动牛犊
  • 注册日期2004-06-29
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于: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" );
}
Levis75
驱动小牛
驱动小牛
  • 注册日期2001-08-06
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分68分
  • 威望7点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-08-03 14:05
what's tx0????
You can write your own usb codes ....
whoIme
驱动牛犊
驱动牛犊
  • 注册日期2004-06-29
  • 最后登录2009-07-08
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望4点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-08-03 14:01
本来我也是象你这么理解的,但我在看D12的固件源码时,发现好像并不是这样的。

因为代码比较长,而且那个代码网上到处都有,我就不发了。
Levis75
驱动小牛
驱动小牛
  • 注册日期2001-08-06
  • 最后登录2006-06-28
  • 粉丝0
  • 关注0
  • 积分68分
  • 威望7点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-08-03 13:52
The normal process is:
SETUP-->
IN_TOKEN-->
Get data from the callback func. then
IN_TOKEN-->
游客

返回顶部