我使用stm32,做电池USB-HID,在使用过程中已经经过初始化成功,在BUS HOUND 抓包过程中,HOST不断向Device发送CTL请求获取report电池的数据。但是只响应c000 0004 stall pid.
我的理解是:红色区域是初始化的步骤,蓝色区域是获取数据的步骤。已经过了初始化的步骤了。
相关程序:
1:这应该是初始化调用相关函数的顺序。
DEVICE_PROP Device_Property =
{
CustomHID_init,
CustomHID_Reset,
CustomHID_Status_In,
CustomHID_Status_Out,
CustomHID_Data_Setup,
CustomHID_NoData_Setup,
CustomHID_Get_Interface_Setting,
CustomHID_GetDeviceDescriptor,
CustomHID_GetConfigDescriptor,
CustomHID_GetStringDescriptor,
0,
0x40 /*MAX PACKET SIZE*/
};
USER_STANDARD_REQUESTS User_Standard_Requests =
{
CustomHID_GetConfiguration,
CustomHID_SetConfiguration,
CustomHID_GetInterface,
CustomHID_SetInterface,
CustomHID_GetStatus,
CustomHID_ClearFeature,
CustomHID_SetEndPointFeature,
CustomHID_SetDeviceFeature,
CustomHID_SetDeviceAddress
};
//CTL处理相关:1
RESULT CustomHID_NoData_Setup(uint8_t RequestNo)
{
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == SET_PROTOCOL))
{
return CustomHID_SetProtocol();
}
//增加如set idle的处理
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == SET_IDLE))
{
return USB_SUCCESS;
}
else
{
return USB_UNSUPPORT;//
}
}
//2
RESULT CustomHID_Data_Setup(uint8_t RequestNo) //枚举1234成功失败不支持
{
uint8_t *(*CopyRoutine)(uint16_t);
if (pInformation->USBwIndex != 0) //接口不=0
return USB_UNSUPPORT;//USB_UNSUPPORT;
CopyRoutine = NULL; //
if ((RequestNo == GET_DESCRIPTOR) // ==6?
&& (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
) // (( ==0x06 ))&&(0x01=(0x00|0x01))
{
if (pInformation->USBwValue1 == REPORT_DESCRIPTOR)
{
CopyRoutine = CustomHID_GetReportDescriptor;
}
else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE)
{
CopyRoutine = CustomHID_GetHIDDescriptor;
}
} /* End of GET_DESCRIPTOR */
/*** GET_PROTOCOL, GET_REPORT, SET_REPORT ***/
else if ( (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) )
{ //USBbmRequestType=后面7位=0x20|0x01=0x0010 0001
switch( RequestNo )
{
case GET_PROTOCOL:
CopyRoutine = CustomHID_GetProtocolValue;
break;
case SET_REPORT:
CopyRoutine = CustomHID_SetReport_Feature;
Request = SET_REPORT;
break;
default:
break;
}
}
if (CopyRoutine == NULL)
{
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
//枚举结果
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process successfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further request */
} RESULT;
相关定义:
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
其它的如get 描述符之类的都能成功。就算没有数据,应该不能
一些说法stall pid=c0000004:
①不管pid回应。按照正常电池回应数据格式发一个数据换上去。但是HoST不认
②是因为没有把数据处理。我的做法是去缓存区把8个字节copy到另外一个数组缓冲到另外一个缓冲区,然后回应vaild有效。但是实测无效
还有一个注意点,在一些callback函数后面回应vaild会打乱usb设备的初始化识别,变成无效设备
③另外一个说法是库函数里没有存在对hid控制传输识别处理:初始化80、81之类的能处理并回应,但是不存在a1的hid 类处理
https://www.usbzh.com/article/detail-686.html
battery-相关工程在下面。可以自己用工具生成usb-report.结题。设备通过usb能通讯显示电量