2010-06-08 09:41 PM
hi~ all
I have developed USB firmware. It send audio stream from imbedded board to PC. But I need PC to send some short packet to imbedded board. I want USB device operate as HID and audio(isochronous IN) at the same time. And, I can not develop Windows device driver. So, I need to use some profile supported by windows default driver. Can I get some usefull USB prifile?? Thanks~!2010-06-11 08:36 AM
Make an audio + HID composite device.
This combination is popular - HID interface passes volume/mute setting from device to PC. Also, supported on in-box drivers on major OSes (Windows, MacOSX and Linux) without any INF file. You can have an optional interrupt OUT endpoint on the HID interface, to pass the data from PC to the device. OR Set_Report (HidD_SetOutputReport() for WinXP and later) is available, too. When the transfer occurs frequently, the interrupt OUT endpoint is better. Before attaching the HID interface to the audio one, I recommend you to examine HID alone on a separate firmware. For this firmware, ''Custom_HID'' example on the ST USB stack is a good starting point. Modify this example, - Move the endpoint address, so that they don't overlap with audio ones. - Simplify the report descriptor, so that it fits to your requirement When you satisfy on the modification, combine HID code into audio. On the configuration descriptor set, - Append HID interface / HID class / endpoint descriptors after the audio interface. - Increase wTotalLength field on the config descriptor by above HID descriptors - Increase bNumInterfaces field of the config descriptor by one - Change bInterfaceNumber field of the HID interface to 2 - Drag in HID report descriptor. For other source files, compare two projects (audio and HID) using a ''diff'' utility like WinMerge. And them combine them. As the interface number of HID interface moves from 0 to 2, you have to touch to the source code in which pInformation->USBwIndex0 is reffered on the HID source. For example, <pre> usb_prop.c for HID enum { INTERFACE_NUMBER_AUDIO_CTRL, INTERFACE_NUMBER_AUDIO_STREAM, INTERFACE_NUMBER_HID, NUM_OF_INTERFACES }; RESULT CustomHID_Data_Setup(uint8_t RequestNo) { uint8_t *(*CopyRoutine)(uint16_t); CopyRoutine = NULL; if ((RequestNo == GET_DESCRIPTOR) && (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT)) // && (pInformation->USBwIndex0 == 0)) // <------------ modified && (pInformation->USBwIndex0 == INTERFACE_NUMBER_HID )) // <------------ to new interface number </pre> WinMerge http://winmerge.org/ Tsuneo2010-06-13 11:45 PM
I really appreciate your reply.
It was helpfull to me. But, I can not understand your example code. I only changed the USB descript file. And I did not change any source code. Now, PC detects my device as a audio device and HID device. But several seconds later, windows returns error about HID. Wondows' message is that ''This device cannot start. (Code 10)''.For debug, I printed usb endpoint data on the screen using Hyper terminal(UART).
Bla bla bla.........
Rx[0]- <- PC send NULL packet Rx[0]- 80 06 20 03 09 04 FF 00 Tx[0]- 2A 03 50 00 56 00 20 00 Tx[0]- 20 00 20 00 4D 00 69 00 Tx[0]- 63 00 72 00 6F 00 70 00 Tx[0]- 68 00 6F 00 6E 00 65 00 Tx[0]- 20 00 20 00 20 00 20 00 Tx[0]- 20 00 Tx[0]- <- I send NULL packet Rx[0]- Rx[0]- 01 0B 00 00 01 00 00 00 Tx[0]- Rx[0]- 21 01 00 01 00 02 01 00 Tx[0]- 00 Rx[0]- A1 82 00 02 00 02 02 00 <-PC request minimum volume value Tx[0]- 00 00 <- I send my minimum volume value Tx[0]- Rx[0]- Rx[0]- A1 83 00 02 00 02 02 00 <- PC request Max volume Tx[0]- 00 01 <- I send my max volume Tx[0]- Rx[0]- Rx[0]- A1 84 00 02 00 02 02 00 <- PC request Vol Resoution Tx[0]- 04 00 <- I send Tx[0]- Rx[0]- Rx[0]- A1 81 00 02 00 02 02 00 <- PC request Current volume Tx[0]- 00 01 <- I send Tx[0]- Rx[0]- Rx[0]- 21 01 00 02 00 02 02 00 <-- PC set my volume Rx[0]- 80 00 <- volume value Tx[0]- Rx[0]- 21 0A 00 00 02 00 00 00 <-- What is that?? I did not send any response.My code is based on KEIL example code.
Could you explain your example code in detail more?Best regards :D
2010-06-14 06:52 AM
> Rx[0]- 21 0A 00 00 02 00 00 00 <-- What is that?? I did not send any response.
It's Set_Idle() request for HID interface.
When you get a SETUP stage of control transfer,
1) check bmRequestType field (the first byte) of the SETUP packet, first.
[D6:D5] bits on bmRequestType shows standard 00, class 01, Vendor 10 requests.
2) for standard request, move to the standard request handler
2') for class request,
the low-byte of wIndex field (the fifth byte) of the SETUP packet shows target interface number.
You've set the interface number of the HID interface to 2 on the config descriptor set.
> My code is based on KEIL example code.
Ah, then, just enabling USB_HID and tune
USB_HID_IF_NUM value
on usbcfg.h,
usbcfg.h
#define USB_HID 1
#define USB_HID_IF_NUM 2
The request handler of KEIL example has already implemented above logic, as follows.
usbcore.c
void USB_EndPoint0 (U32 event) {
switch (event) {
case USB_EVT_SETUP:
...
switch (SetupPacket.bmRequestType.BM.Type) {
case REQUEST_STANDARD:
...
...
...
#if USB_CLASS
case REQUEST_CLASS:
switch (SetupPacket.bmRequestType.BM.Recipient) {
case REQUEST_TO_DEVICE:
goto stall_i; /* not supported */
case REQUEST_TO_INTERFACE:
#if USB_HID
if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM) { // <---- request to HID interface
...
...
}
#endif /* USB_HID */
#if USB_AUDIO
if ((SetupPacket.wIndex.WB.L == USB_ADC_CIF_NUM) ||
// <---- request to Audio interface
(SetupPacket.wIndex.WB.L == USB_ADC_SIF1_NUM) ||
(SetupPacket.wIndex.WB.L == USB_ADC_SIF2_NUM)) {
...
...
}
#endif /* USB_AUDIO */
Tsuneo
2010-06-15 04:29 AM
Thank you for your help.
It is really helpfull to me!!! How can I ever repay you? Thank you very much Mr,Tsuneo. I really appreciate your help. :) Best regards : )