处理有数据的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
命令 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
Get_Descriptor | 10000000B | GET_DESCRIPTOR | 描述表种类(高字节)和索引(低字节) | 0或语言标志 | 描述表长度 | 描述表 |
这里只读取的标准描述符,类描述符并没有处理。标准描述符的种类值如下表。
描述符 | 描述符值 |
设备描述符(Device Descriptor) | 0x01 |
配置描述符(Configuration Descriptor) | 0x02 |
字符串描述符(String Descriptor) | 0x03 |
接口描述符(Interface Descriptor) | 0x04 |
端点描述符(EndPont Descriptor) | 0x05 |
b. GET_STATUS
命令 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
Get_Status | 10000000B 10000001B 10000010B | GET_STATUS | 0 | 0(返回设备状态) 接口号(对象是接口时) 端点号(对象是端点时) | 2 | 设备状态 |
Get_Status命令对设备,接口,端点都有效,wValue都是0,而wIndex根据设备,接口,端点有不同的意义,而wIndex一定是2,接接下来的Data数据一定是2个字节。
c. GET_CONFIGURATION
命令 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
Get_Configuration | 10000000B | GET_CONFIGURATION | 0 | 0 | 1 | 配置值 |
d. GET_INTERFACE
命令 | bmRequestType | bRequest | wValue | wIndex | wLength | Data |
Get_Interface | 10000001B | GET_INTERFACE | 0 | 接口号 | 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应该是记录下需要传输的数据长度。