HID Feature
I have implemented a detach feature in a HID device which report descriptor is:
const BYTE IPLB_ReportDescriptor[IPLB_SIZ_REPORT_DESC] = {
0x06, 0xA0, 0xFF, // USAGE_PAGE (Consumer Page) 0x09, 0x01, // USAGE (Consumer Control Usage 0x01) 0xA1, 0x01, // COLLECTION (Application)
//INPUT 0x09, 0x03, 0x15, 0x00, // LOGICAL_MINIMUM(0) 0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM(255) 0x75, 0x08, // REPORT_SIZE 0x95, BUFFER_SIZE, // REPORT_COUNT 0x81, 0x02, // INPUT (Data, Variable,Abs)
//OUTPUT 0x09, 0x04, 0x15, 0x00, // LOGICAL_MINIMUM(0) 0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM(255) 0x75, 0x08, // REPORT_SIZE 0x95, BUFFER_SIZE, // REPORT_COUNT 0x91, 0x02, // OUTPUT (Data, Variable,Abs)
//Feature 0x09, 0x05, 0x15, 0x00, // LOGICAL_MINIMUM(0) 0x26, 0xFF, 0x00, // LOGICAL_MAXIMUM(255) 0x75, 0x08, // REPORT_SIZE 0x95, BUFFER_SIZE, // REPORT_COUNT 0xB1, 0x02, // Feature (Data, Variable,Abs)
//DETACH FEATURE 0x06,0x00,0xFF, 0x09,0x55, 0x15,0x00, 0x26,0xFF,0x00, 0x75,0x08, 0x95,BUFFER_SIZE, 0xB1,0x82, 0xC0 // END_COLLECTION }
In my software I am able to detect the device, to recognize the detach feature ability using:
while ((cnt < pWalk->Caps.NumberFeatureValueCaps) { if (pValue->UsagePage == VENDOR_USAGE_PAGE) { HidDetachFound = true; break; } cnt ++; pValue++; }
but when I send the Set_feature request I have no answer from the device?!
if (!HidD_SetFeature(pWalk->HidDevice, Feature,64)) HandleTxtError("Unable to enter DFU mode: Set Feature HID Detach failed !"); else { Sleep(1000); HandleTxtSuccess("Successfully entered DFU Mode !"); AfxMessageBox("Detach command successful ! Device list refresh will be done...\n\nPlease re-select your device in DFU mode"); Refresh(); }
This set_feature request uses a control transfer (EP0) but debugging in my firmware on the USB_CORE I see no data arriving.
Does someone have an idea where the problem can be, any help will be welcome!
Leave it Tsuneo, I have just solve it with a flag. It is working now! Thanks a lot for all your help and have a nice week!
Milton
Please post more specific information about what you had to do to fix your problem. If you just end this thread with your last post, other people who find this thread will not know about what you did...
Maybe he wasn't aware to modify "(*CopyRoutine)(0);" line, because I missed to highlight it in above post.
RESULT IPLB_Data_Setup(BYTE RequestNo) { ... (*CopyRoutine)(0); // pbLen = (*CopyRoutine)(0); // delete these lines // wLen = (WORD)((DWORD)pbLen); // pInfo->Ctrl_Info.Usb_wLength = wLen; return USB_SUCCESS; } /* IPLB_Data_Setup */
The implementation of HID Set_Report request is same as CDC Set_Line_Coding. Both requests are carried over Control Write transfer.
Actually, I referred the CDC example of the ST USB stack to make above code.
Tsuneo
Hi!
I saw the line but it wasn't working anyway. What I did to solve it was:
else if ( (RequestNo == SET_REPORT) && (pInfo->USBwValue1 == HID_FEATURE) ) { CopyRoutine = IPLB_SetReport; Request = SET_REPORT; // detach feature falls here! feature_flag=1; } } if (CopyRoutine == NULL) return UNSUPPORT; pInfo->Ctrl_Info.CopyData = CopyRoutine; pInfo->Ctrl_Info.Usb_wOffset = 0; if (feature_flag==1) { (*CopyRoutine)(0); feature_flag=0; } else { pbLen = (*CopyRoutine)(0); wLen = (WORD)((DWORD)pbLen); pInfo->Ctrl_Info.Usb_wLength = wLen; } return USB_SUCCESS; } /* IPLB_Data_Setup */
So it only uses (*CopyRoutine)(0); if it is a feature request. If I will use it for all requests the device is not recognize anymore ...
Humm.. Seems that the version of the stack is different... I referred the latest stack from ST Micro web page.
In the recent stack, this process is done in the "CopyRoutine", assigned in each request.
pbLen = (*CopyRoutine)(0); wLen = (WORD)((DWORD)pbLen); pInfo->Ctrl_Info.Usb_wLength = wLen;
In your code, the GetProtocol handler is as follows,
BYTE *Mouse_GetProtocolValue(WORD Length) { return (BYTE *)&ProtocolValue; }
In the recent stack (Sep-2008) from ST Micro "STR7/STR9 USB developer kit software" www.st.com/.../um0290.zip
u8 *Joystick_GetProtocolValue(u16 Length) { if (Length == 0) { pInformation->Ctrl_Info.Usb_wLength = 1; return NULL; } else return (u8 *)(&ProtocolValue); }
Maybe they've revised it in the recent stack.