Closed xfce closed 1 year ago
What OS are you using? It successfully detects on linux with ALSA, but fails on Windows. I guess, Windows can't receive all string descriptors. TDD log:
String Descriptor Table
Index LANGID String
0x00 0x0000
0x01 0x0000 Request failed with 0x0000001F
0x02 0x0000 Request failed with 0x0000001F
@xfce Hello. The device is of generic Audio Class and it doesn't need a driver. I tested the firmware under Linux only. Probably there's an issue with the descriptor as mentioned by @viteo. Sorry for that.
One assumption is that I used 4 bytes for the tSamFreq
instead of 3 as required by the USB specification. As I remember Linux complains on that but just ignores the fourth byte. Try to change the line to .byte 0x00, 0xee, 0x02
. Or maybe it's unrelated and an issue in the strings themselves.
I've changed tSamFreq
to 3 bytes. Still same error.
I found something interesting worth consider: in the TinyUSB examples there is a comment
the Windows driver always needs an extra sample per channel of space more, otherwise it complains... found by trial and error
Might it be related to this issue? I'm not sure what to modify in the code: set_ep1_counters
maybe?
set_ep1_counters maybe?
I don't quite remember:) Seems set_ep1_counters()
sets the actual count of bytes to be sent, while TinyUSB's example alters endpoint buffer size which is, in our case, equals to 512 bytes, 128 bytes more than needed. In another TinyUSB example for mono audio device they don't add an extra sample. Therefore I don't think this is related.
It's hard to tell what's going on without seeing the exact USB connection log. Probably the issue is in the device configuration phase. Or maybe it's just "wrong" VID:PID pair.
In another TinyUSB example for mono audio device they don't add an extra sample.
yeah. but that example fails to initialize. but ok, this might not be related.
I've tried to capture usb log with WireShark + pCap. It looks wierd, but it is software analyzer (maybe you could suggest something more suitable for usb traffic analysis).
Host requests several times the same String descriptor with index=2 ("Prod"), but the Device answers differs: "P" then "Prod" then again "P" then "Prod" and then communication stops. Request Anwser full log for wireshark: usb_audio.zip
I've tried to feed to get_descriptor()
predefined hand-written string descriptors, but nothing changed in the initialization log. Tried short length descriptors to fit in 8 byte EP0 buffer, but nothing changed.
Something with epn_tx()
and bytes_remain
in it? No more ideas for now.
@viteo
Thank you, Viktar, I will take a look at this as soon as possible.
maybe you could suggest something more suitable for usb traffic analysis
I think that Wireshark is pretty good choice. USBPcap is what Wireshark itself recommends.
Ok, the log looks good to me until host-device communication stops. Probably "Unknown type" function code (URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR
) is just ignored. What about string descriptors requests — they're fine, a host first try find string descriptor length by requesting only 4 bytes (Setup Data -> wLength: 4
) of a descriptor, these 4 bytes contain total string descriptor length information + first string letter ("P"). With subsequent request, knowing full string length, host receives entire string.
To me it looks like device eventually "stalls" and becomes unavailable. Maybe. But I can't see any other host -> device requests that would make it unresponsive. STALL
condition may be checked by adding if (status == STALL) LED_OFF();
to the ep0_set_stat_tx()
function. Then if this is the case the onboard LED (PC13
) will go off.
What also strange is that there's no string descriptor 0 (language ID) request but when host requests a string it already knows the ID. AFAIK there's no default LANG_ID. Maybe something is missing in the log.
It is really in STALL
condition, led turns off almost immediately.
I've tried another approach to get USB log with virtual machine. It looks almost the same. LangID
request is present.
vusb-analyzer on WSL + Ubuntu 16
vm_usb.log
I see that host requests a Device_Qualifier
descriptor (GetDescriptor(0x06, 0)
, response text is in red on the image) which is not implemented. USB 2.0 specification says:
9.6.2 Device_Qualifier: If a full-speed only device (with a device descriptor version number equal to 0200H) receives a GetDescriptor() request for a device_qualifier, it must respond with a request error.
So, this is our case. "Request error" means:
9.2.7 Request Error: When a request is received by a device that is not defined for the device, is inappropriate for the current setting of the device, or has values that are not compatible with the request, then a Request Error exists. The device deals with the Request Error by returning a STALL PID in response to the next Data stage transaction or in the Status stage of the message. It is preferred that the STALL PID be returned at the next Data stage transaction, as this avoids unnecessary bus activity.
Everything is ok to this point. Next comes another standard configuration phase and then strange repeating string descriptor requests after which all communication stops. Maybe MCU hangs?
Based on the logs there's no reason for the device to stop responding. I don't see it. Last GetDescriptor()
request has been responded, according to the attached vm_usb.log.
Maybe try to implement Device_Qualifier
descriptor?
I've implemented Device_Qualifier
descriptor and added LED toggle in while(PWR)
.
Descriptor request answered, MCU doesn't hang.
Also I found logic analyzer and sniff USB lines with Sigrok's PulseView, then convert data to WireShark. Here is filtered result: Wireshark 4.0.1 dslog_usb.zip
Wow, that's awesome! Thank you, I'm already trying to investigate the problem)
@viteo Viktar, you will be laughing but I don't see any problem. All descriptors were transferred successfully with acknowledgements from both sides.
So it seems that Windows doesn't like these descriptors. Though all string descriptors are optional, maybe fill in iSerialNumber
from device_descriptor
? Another assumption is that Interface descriptor is malformed from the Windows' point of view.
Have a look to these projects:
I know that STM has it's own registered VID for their example USB devices, maybe try to use VID:PID as in the second project?
Well, the only big difference is that they both (1, 2) have Alternate Setting (with 0 endpoints) for AS Interface Descriptor. I've read somewhere that this alternate setting is used to disable streaming.
So, I've added it. Not sure how to handle this request properly, because looks like they are just ignoring this. I've uncommented current_configuration
lines.
But now, the device is no longer recognized in Device Manager.
usb_fault.zip
It looked like this before:
Compared descriptors byte-to-byte and changed:
bTerminalID
swTerminalType
to 0x0201 == MiciSerialNumber
Differences left:
I've read somewhere that this alternate setting is used to disable streaming.
I remember something, but I'm not sure whether an interface altsetting with 0 endpoints is strictly required for audio class devices. Specification only says that a device "may" or "can" have interface alternate settings. There is an example of USB Microphone at p.105, it also has altsetting with 0 endpoints:
The descriptors diff for the altsetting could look something like:
--- descriptors_audio.s
+++ descriptors_audio.s
@@ -121,0 +122,12 @@
+ interface_descriptor_as_alt:
+ .byte IDAS_ALT_SZ @; bLength
+ .byte DESC_TYPE_INTERFACE @; bDescriptorType
+ .byte 1 @; bInterfaceNumber : Zero based
+ .byte 0 @; bAlternateSetting
+ .byte 0 @; bNumEndpoints = No endpoints interface altsetting
+ .byte 0x01 @; bInterfaceClass = AUDIO
+ .byte 0x02 @; bInterfaceSubClass = AUDIO_STREAMING
+ .byte 0 @; bInterfaceProtocol = No protocol
+ .byte 0 @; iInterface
+ IDAS_ALT_SZ = . - interface_descriptor_as_alt
+
@@ -126 +138 @@
- .byte 0 @; bAlternateSetting
+ .byte 1 @; bAlternateSetting
Not sure how to handle this request properly
Try to "uncomment" line #418 by writing #if 1
. Otherwise SetInterface()
and GetInterface()
requests will be stalled. Though I don't see any in the log attached.
Isochronous endpoint buffer size is the maximum bytes to be transferred at each USB frame which, for Full Speed USB 2.0, happens every 1 ms. Actual number of bytes to be transferred may vary and don't have to be equal to EP buffer size, it may be less. If you want to change the setting, just type in any value you wish to EP1_BUF_SZ
, e.g. (192+1)*2
.
yep. alt setting was the issue with windows driver
Woohoo! 🎉
Glad to hear that :)
Hi, I update the usb_audio_flash.bin file, and the PC system can find the USB AUDIO DEVICE, and display the name Prod, but didn't find the correct driver, when can I find the driver, thanks