基于STM32F103的USB学习笔记21 - Data_Setup0

72 篇文章 41 订阅

处理有数据的SETUP过程。

void Data_Setup0(void)
{
    uint8_t *(*CopyRoutine)(uint16_t);
    RESULT Result;
    uint32_t Request_No = pInformation->USBbRequest;

    uint32_t Related_Endpoint, Reserved;
    uint32_t wOffset, Status;

    CopyRoutine = NULL;
    wOffset = 0;


    /*GET DESCRIPTOR*/ //具体看后面说明a.
    if (Request_No == GET_DESCRIPTOR) //获取描述符
    {
        if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT)) //是设备的标准请求
        {
            uint8_t wValue1 = pInformation->USBwValue1; //wValue的高字节表示是哪种描述符
            if (wValue1 == DEVICE_DESCRIPTOR)
            {
                CopyRoutine = pProperty->GetDeviceDescriptor;
            }
#ifdef LPM_ENABLED
            else if (wValue1 == DEVICE_BOS_DESCRIPTOR)
            {
                CopyRoutine = pProperty->GetBosDescriptor;
            }
#endif
            else if (wValue1 == CONFIG_DESCRIPTOR)
            {
                CopyRoutine = pProperty->GetConfigDescriptor;
            }
            else if (wValue1 == STRING_DESCRIPTOR)
            {
                CopyRoutine = pProperty->GetStringDescriptor;
            }  /* End of GET_DESCRIPTOR */
        }
    }
    /*GET STATUS*/ //具体看后面说明b.
    else if ((Request_No == GET_STATUS) && (pInformation->USBwValue == 0)
        && (pInformation->USBwLength == 0x0002)
        && (pInformation->USBwIndex1 == 0))
    {
        /* GET STATUS for Device*/
        if ((Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
            && (pInformation->USBwIndex == 0))
        {
            CopyRoutine = Standard_GetStatus;
        }
        /* GET STATUS for Interface*/
        else if (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
        {
            if (((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS)
                && (pInformation->Current_Configuration != 0)) //检测接口是否有效和配置描述符是否已经拿到
            {
                CopyRoutine = Standard_GetStatus;
            }
        }
        /* GET STATUS for EndPoint*/
        else if (Type_Recipient == (STANDARD_REQUEST | ENDPOINT_RECIPIENT))
        {
            Related_Endpoint = (pInformation->USBwIndex0 & 0x0f); //获得端点号
            Reserved = pInformation->USBwIndex0 & 0x70; //读入预留位
            if (ValBit(pInformation->USBwIndex0, 7)) //根据方向读取这个方向上的Status值
            {
                /*Get Status of endpoint & stall the request if the related_ENdpoint
                is Disabled*/
                Status = _GetEPTxStatus(Related_Endpoint);
            }
            else
            {
                Status = _GetEPRxStatus(Related_Endpoint);
            }
            if ((Related_Endpoint < Device_Table.Total_Endpoint) && (Reserved == 0)
                && (Status != 0)) //Status不等于0表示端点没有被忽略所有读或写请求
            {
                CopyRoutine = Standard_GetStatus;
            }
        }
    }
    /*GET CONFIGURATION*/ //具体看后面说明c.
    else if (Request_No == GET_CONFIGURATION)
    {
        if (Type_Recipient == (STANDARD_REQUEST | DEVICE_RECIPIENT))
        {
            CopyRoutine = Standard_GetConfiguration;
        }
    }
    /*GET INTERFACE*/ //具体看后面说明d.
    else if (Request_No == GET_INTERFACE)
    {
        if ((Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
            && (pInformation->Current_Configuration != 0) && (pInformation->USBwValue == 0)
            && (pInformation->USBwIndex1 == 0) && (pInformation->USBwLength == 0x0001)
            && ((*pProperty->Class_Get_Interface_Setting)(pInformation->USBwIndex0, 0) == USB_SUCCESS))
        {
            CopyRoutine = Standard_GetInterface;
        }
    }
  
    if (CopyRoutine)
    {
        pInformation->Ctrl_Info.Usb_wOffset = wOffset;
        pInformation->Ctrl_Info.CopyData = CopyRoutine;
        /* sb in the original the cast to word was directly */
        /* now the cast is made step by step */
        (*CopyRoutine)(0);  //pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset,wOffset = 0
        Result = USB_SUCCESS;
    }
    else
    {//不是标准的Setup,执行usb_prop.c中用户自定义的Setup函数
        Result = (*pProperty->Class_Data_Setup)(pInformation->USBbRequest);
        if (Result == USB_NOT_READY)
        {
            pInformation->ControlState = PAUSE;
            return;
        }
    }

    if (pInformation->Ctrl_Info.Usb_wLength == 0xFFFF)
    {//等于0xffff表示数据没有准备好,ControlState设置为PAUSE并返回。
        /* Data is not ready, wait it */
        pInformation->ControlState = PAUSE;
        return;
    }
    if ((Result == USB_UNSUPPORT) || (pInformation->Ctrl_Info.Usb_wLength == 0))
    {//表示不支持的请求,ControlState设置为STALLED并返回。
        /* Unsupported request */
        pInformation->ControlState = STALLED;
        return;
    }

    if (ValBit(pInformation->USBbmRequestType, 7))
    {//判断是不是IN
        /* Device ==> Host */
        __IO uint32_t wLength = pInformation->USBwLength; //Host要求的数据长度
     
        /* Restrict the data length to be the one host asks for */
        if (pInformation->Ctrl_Info.Usb_wLength > wLength)
        {//实际数据长度大于Host要求的数据长度
            pInformation->Ctrl_Info.Usb_wLength = wLength;
        }
        else if (pInformation->Ctrl_Info.Usb_wLength < pInformation->USBwLength)
        {//实际数据长度小于Host要求的数据长度
            if (pInformation->Ctrl_Info.Usb_wLength < pProperty->MaxPacketSize)
            {//实际数据长度小于包的最大大小
                Data_Mul_MaxPacketSize = FALSE;
            }
            else if ((pInformation->Ctrl_Info.Usb_wLength % pProperty->MaxPacketSize) == 0)
            {//实际数据长度是包的最大大小的整数倍
                Data_Mul_MaxPacketSize = TRUE;
            }
        }   
        pInformation->Ctrl_Info.PacketSize = pProperty->MaxPacketSize;
        DataStageIn(); //读取传输的数据
    }
    else
    {
        pInformation->ControlState = OUT_DATA;  //表示下个阶段是HOST输出数据到设备
        vSetEPRxStatus(EP_RX_VALID); /* enable for next data reception */
    }

    return;
}

a. GET_DESCRIPTOR

命令bmRequestTypebRequestwValuewIndexwLengthData
Get_Descriptor10000000BGET_DESCRIPTOR描述表种类(高字节)和索引(低字节)0或语言标志描述表长度描述表

这里只读取的标准描述符,类描述符并没有处理。标准描述符的种类值如下表。

描述符描述符值
设备描述符(Device Descriptor)0x01
配置描述符(Configuration Descriptor)0x02
字符串描述符(String Descriptor)0x03
接口描述符(Interface Descriptor)0x04
端点描述符(EndPont Descriptor)0x05

b. GET_STATUS

命令bmRequestTypebRequestwValuewIndexwLengthData
Get_Status10000000B
10000001B
10000010B
GET_STATUS00(返回设备状态)
接口号(对象是接口时)
端点号(对象是端点时)
2

设备状态
接口状态
端点状态

Get_Status命令对设备,接口,端点都有效,wValue都是0,而wIndex根据设备,接口,端点有不同的意义,而wIndex一定是2,接接下来的Data数据一定是2个字节。

c. GET_CONFIGURATION

命令bmRequestTypebRequestwValuewIndexwLengthData
Get_Configuration10000000BGET_CONFIGURATION001配置值

d. GET_INTERFACE

命令bmRequestTypebRequestwValuewIndexwLengthData
Get_Interface10000001BGET_INTERFACE0接口号1可选设置

 

获取标准的描述符的代码都类似,都是调用库函数Standard_GetDescriptorData

uint8_t *Standard_GetDescriptorData(uint16_t Length, ONE_DESCRIPTOR *pDesc)
{
  uint32_t  wOffset;

  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
  if (Length == 0)
  {
    pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size - wOffset;
    return 0;
  }

  return pDesc->Descriptor + wOffset;
}

这里Length都是位0,所以执行的结果是pInformation->Ctrl_Info.Usb_wLength = pDesc->Descriptor_Size;

pInformation->Ctrl_Info.Usb_wLength应该是记录下需要传输的数据长度。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值