No data received form USB device - usb
I'm implementing USB web cam on top of Atmega32U4.
I think I managed to implement transactions on the control endpoint, more or less correctly, as all the descriptors are transited and device reports correctly in the system.
Issue is when I'm trying to send video data out of the device, as nothing seems to go through.
The way I implemented data transmission (according to section 22.14 of datasheet) is as follows:
while (len > 0) {
while (1) {
cli();
_select_endpoint(VIDEO_STREAMING_ENDPOINT);
if (bit_is_set(UEINTX, TXINI) && bit_is_set(UEINTX, FIFOCON))
break;
sei();
_delay_ms(1);
}
_clear_TXINI();
while (bit_is_set(UEINTX, RWAL) && len > 0) {
UEDATX = *buff++;
--len;
}
_clear_FIFOCON();
sei();
}
When debugging this I noticed that bank is filled with data during the first loop, but data is not transmitted to the host. It is looping forever in the TXINI,FIFOCON part. Nothing, except the control requests, is shown in the Wireshark. I'm not sure if I missconfigured something on the MCU registers, so it is not sending data to the host upon the request, or in the descriptors, status, etc, so host is not asking for data.
What might have I messed up?
lsusb -v
Bus 001 Device 077: ID 6431:deb2 majkrzak majkrzak
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 32
idVendor 0x6431
idProduct 0xdeb2
bcdDevice 0.00
iManufacturer 1 majkrzak
iProduct 1 majkrzak
iSerial 1 majkrzak
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x00a0
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 1 majkrzak
bmAttributes 0x80
(Bus Powered)
MaxPower 500mA
Interface Association:
bLength 8
bDescriptorType 11
bFirstInterface 0
bInterfaceCount 2
bFunctionClass 14 Video
bFunctionSubClass 3 Video Interface Collection
bFunctionProtocol 0
iFunction 1 majkrzak
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 14 Video
bInterfaceSubClass 1 Video Control
bInterfaceProtocol 1
iInterface 1 majkrzak
VideoControl Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdUVC 1.50
wTotalLength 0x0028
dwClockFrequency 16.000000MHz
bInCollection 1
baInterfaceNr( 0) 1
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 2
iTerminal 1 majkrzak
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00000000
VideoControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0101 USB Streaming
bAssocTerminal 1
bSourceID 1
iTerminal 1 majkrzak
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 14 Video
bInterfaceSubClass 2 Video Streaming
bInterfaceProtocol 1
iInterface 1 majkrzak
VideoStreaming Interface Descriptor:
bLength 13
bDescriptorType 36
bDescriptorSubtype 1 (INPUT_HEADER)
bNumFormats 1
wTotalLength 0x0055
bEndpointAddress 0x81 EP 1 IN
bmInfo 0
bTerminalLink 2
bStillCaptureMethod 0
bTriggerSupport 0
bTriggerUsage 0
bControlSize 0
bmaControls( 0) 27
VideoStreaming Interface Descriptor:
bLength 27
bDescriptorType 36
bDescriptorSubtype 4 (FORMAT_UNCOMPRESSED)
bFormatIndex 1
bNumFrameDescriptors 1
guidFormat {32595559-0000-0010-8000-00aa00389b71}
bBitsPerPixel 8
bDefaultFrameIndex 0
bAspectRatioX 1
bAspectRatioY 1
bmInterlaceFlags 0x00
Interlaced stream or variable: No
Fields per frame: 2 fields
Field 1 first: No
Field pattern: Field 1 only
bCopyProtect 0
VideoStreaming Interface Descriptor:
bLength 38
bDescriptorType 36
bDescriptorSubtype 5 (FRAME_UNCOMPRESSED)
bFrameIndex 1
bmCapabilities 0x02
Still image unsupported
Fixed frame-rate
wWidth 16
wHeight 16
dwMinBitRate 262144
dwMaxBitRate 262144
dwMaxVideoFrameBufferSize 768
dwDefaultFrameInterval 1000000
bFrameIntervalType 0
dwMinFrameInterval 1000000
dwMaxFrameInterval 1000000
dwFrameIntervalStep 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0020 1x 32 bytes
bInterval 1
Device Status: 0x0000
(Bus Powered)
edit
I'd made a simple script with pyusb which is pulling data from the endpoint and it works. Wireshark is showing the transactions, so it means that in the uvcvideo case data is not pulled at all. Definitely I messed up the descriptors then.
The reason why uvc driver is not pulling any data for the device, is that you set dwMaxVideoFrameSize and dwMaxPayloadTransferSize to 0. Set it to value high enough for your case and it will work.
Related
Missing out endpoint for a relay
Connecting to a usb-relay (https://www.amazon.de/ARCELI-SRD-05VDC-SL-C-Relaismodul-steuerschalter-intelligente/dp/B07J2PY13G/ref=sr_1_15?crid=1OQO4UWC6499D&keywords=usb+relais+5v&qid=1647548932&sprefix=usb+relais%2Caps%2C179&sr=8-15) from a windows 10 pc I only get information of existing IN-ENDPOINT. But I am missing the OUT-ENDPOINT. What did I wrong ? I installed 3 drivers via libusbK-3.1.0.0-setup.exe: WinUsb v6.1.7600.16385 (04/09/2017) libusbK v3.0.7.0 (07/19/2021) libusb0 v1.2.6.0 (06/17/2021) Using a python-script import usb.core import usb.util dev = usb.core.find(idVendor=0x16C0, idProduct=0x05DF) if dev is None: raise ValueError('Device not found') dev.set_configuration() cfg = dev.get_active_configuration() intf = cfg[(0,0)] print ('cfg ',cfg) ep = usb.util.find_descriptor( intf, custom_match = \ lambda e: \ usb.util.endpoint_direction(e.bEndpointAddress) == \ usb.util.ENDPOINT_OUT) print ('ENDPOINT ',ep) I got cfg CONFIGURATION 1: 20 mA =================================== bLength : 0x9 (9 bytes) bDescriptorType : 0x2 Configuration wTotalLength : 0x22 (34 bytes) bNumInterfaces : 0x1 bConfigurationValue : 0x1 iConfiguration : 0x0 bmAttributes : 0x80 Bus Powered bMaxPower : 0xa (20 mA) INTERFACE 0: Human Interface Device ==================== bLength : 0x9 (9 bytes) bDescriptorType : 0x4 Interface bInterfaceNumber : 0x0 bAlternateSetting : 0x0 bNumEndpoints : 0x1 bInterfaceClass : 0x3 Human Interface Device bInterfaceSubClass : 0x0 bInterfaceProtocol : 0x0 iInterface : 0x0 ENDPOINT 0x81: Interrupt IN ========================== bLength : 0x7 (7 bytes) bDescriptorType : 0x5 Endpoint bEndpointAddress : 0x81 IN bmAttributes : 0x3 Interrupt wMaxPacketSize : 0x8 (8 bytes) bInterval : 0x14 ENDPOINT-OUT: None
can I get 255 packets from VCP (virtual COM Port)?
I know the default setting value for 'VIRTUAL_COM_PORT_DATA_SIZE 64' at usb_desc.h for STM32 Library. however, I want to get the 255 bytes at one time due to the long packets of our project. So I have changed the following modify code point, I couldn't get the right value with problem for 'USB defect problem'. /****** usb_prop.c **********/ DEVICE_PROP Device_Property = { Virtual_Com_Port_init, Virtual_Com_Port_Reset, Virtual_Com_Port_Status_In, Virtual_Com_Port_Status_Out, Virtual_Com_Port_Data_Setup, Virtual_Com_Port_NoData_Setup, Virtual_Com_Port_Get_Interface_Setting, Virtual_Com_Port_GetDeviceDescriptor, Virtual_Com_Port_GetConfigDescriptor, Virtual_Com_Port_GetStringDescriptor, 0, 0xFF /*MAX PACKET SIZE*/ // default : 0x40 }; /****** usb_desc.c **********/ /* USB Standard Device Descriptor */ const uint8_t Virtual_Com_Port_DeviceDescriptor[] = { 0x12, /* bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, 0x02, /* bcdUSB = 2.00 */ 0x02, /* bDeviceClass: CDC */ 0x00, /* bDeviceSubClass */ 0x00, /* bDeviceProtocol */ 0xFF, /* bMaxPacketSize0 */ // default : 0x40 0x83, 0x04, /* idVendor = 0x0483 */ 0x40, 0x57, /* idProduct = 0x7540 */ 0x00, 0x02, /* bcdDevice = 2.00 */ 1, /* Index of string descriptor describing manufacturer */ 2, /* Index of string descriptor describing product */ 3, /* Index of string descriptor describing the device's serial number */ 0x01 /* bNumConfigurations */ }; /****** usb_desc.h **********/ #define VIRTUAL_COM_PORT_DATA_SIZE 255 // 0xFF, default : 64 please tell me how to modify in order to send as 255 bytes from USB packets.
You can't do it this way. The size of the packet is USB endpoint related and for the FS USB it is always 64 bytes. My advice is: do not modify any descriptors unless you really know what are you doing (which is not the case here). How to receive larger chunks of data: create a buffer when data arrives copy it (append) to that buffer check if you have received all data needed if not go to point (2) else goto point(5) Do something with the data (your large packet) Reset the buffer and goto point 2
USB CDC work only once w/ interupt endp
I'm implementing a Virtual COM port on an STM32F4 MCU. The MCU don't have endpoints left available so I have to revome interupt endpoint/notification element. The problem is the MCU can send a message to the pc only once, after the pc will not get it. The device USB descriptor: Interface Association Descriptor: ------------------------------ 0x08 bLength 0x0B bDescriptorType 0x02 bFirstInterface 0x02 bInterfaceCount 0x02 bFunctionClass (Communication Device Class) 0x02 bFunctionSubClass (Abstract Control Model) 0x01 bFunctionProtocol (ITU-T V.250) 0x06 iFunction Interface Descriptor: ------------------------------ 0x09 bLength 0x04 bDescriptorType 0x02 bInterfaceNumber 0x00 bAlternateSetting 0x00 bNumEndPoints 0x02 bInterfaceClass (Communication Device Class) 0x02 bInterfaceSubClass (Abstract Control Model) 0x01 bInterfaceProtocol (ITU-T V.250) 0x02 iInterface "" CDC Header Functional Descriptor: ------------------------------ 0x05 bFunctionalLength 0x24 bDescriptorType 0x00 bDescriptorSubtype 0x0110 bcdCDC CDC Call Management Functional Descriptor: ------------------------------ 0x05 bFunctionalLength 0x24 bDescriptorType 0x01 bDescriptorSubtype 0x00 bmCapabilities 0x01 bDataInterface CDC Abstract Control Management Functional Descriptor: ------------------------------ 0x04 bFunctionalLength 0x24 bDescriptorType 0x02 bDescriptorSubtype 0x02 bmCapabilities CDC Union Functional Descriptor: ------------------------------ 0x05 bFunctionalLength 0x24 bDescriptorType 0x06 bDescriptorSubtype 0x00 bControlInterface 0x01 bSubordinateInterface(0) Interface Descriptor: ------------------------------ 0x09 bLength 0x04 bDescriptorType 0x03 bInterfaceNumber 0x00 bAlternateSetting 0x02 bNumEndPoints 0x0A bInterfaceClass (CDC Data) 0x00 bInterfaceSubClass 0x00 bInterfaceProtocol 0x02 iInterface "" Endpoint Descriptor: ------------------------------ 0x07 bLength 0x05 bDescriptorType 0x03 bEndpointAddress (OUT Endpoint) 0x02 bmAttributes (Transfer: Bulk / Synch: None / Usage: Data) 0x0010 wMaxPacketSize (16 Bytes) 0x00 bInterval Endpoint Descriptor: ------------------------------ 0x07 bLength 0x05 bDescriptorType 0x85 bEndpointAddress (IN Endpoint) 0x02 bmAttributes (Transfer: Bulk / Synch: None / Usage: Data) 0x0010 wMaxPacketSize (16 Bytes) 0x00 bInterval
If i remove this useless endpoint the usbser windows driver go nuts. So You have to have an interupt IN endpoint even if the application never ever use it.
STM32 USB HID reports
For the past two weeks I have been trying to configure my card (STM32F4) to dialogue with USB HID with a PC under Windows 7. I make success with this descriptor: __ALIGN_BEGIN static uint8_t HID_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x06, 0xFF, 0x00, // USAGE_PAGE (Vendor Page: 0xFF00) 0x09, 0x01, // USAGE (Demo Kit) 0xa1, 0x01, // COLLECTION (Application) //0x85, 0x01, // REPORT_ID (1) 0x09, 0x02, // USAGE (DATA) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x26, 0xff,0x00, // LOGICAL_MAXIMUM (255) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x81, 0x02, // INPUT (Data,Var,Abs,Vol) 0xc0 // END_COLLECTION }; Like this, Windows recognizeS my card like a compliant HID component. Now if I want to send 32 bit data like a uint32, Windows recognizes the card, but it sees an error to tell that it can't start it! My descriptor: __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x06, 0xFF, 0x00, // USAGE_PAGE (Vendor Page: 0xFF00) 0x09, 0x01, // USAGE (Demo Kit) 0xa1, 0x01, // COLLECTION (Application) 0x09, 0x02, // USAGE (DATA) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x27, 0xff,0xff,0xff,0xff, // LOGICAL_MAXIMUM (65535) 0x75, 0x20, // REPORT_SIZE (32) 0x95, 0x01, // REPORT_COUNT (1) 0x81, 0x02, // INPUT (Data,Var,Abs,Vol) 0xc0 // END_COLLECTION }; I didn't understand why it din't work! After that, I use USBlyser to scan my other USB device on my PC, and I take this descriptor about my spacespilot 3D mouse: Endpoint Descriptor 83 3 In, Interrupt, 16 ms Offset Field Size Value Description 0 bLength 1 07h 1 bDescriptorType 1 05h Endpoint 2 bEndpointAddress 1 83h 3 In 3 bmAttributes 1 03h Interrupt 1..0: Transfer Type ......11 Interrupt 7..2: Reserved 000000.. 4 wMaxPacketSize 2 0007h 7 bytes 6 bInterval 1 08h 16 ms Interface 1 HID Report Descriptor Multi-Axis Controller Item Tag (Value) Raw Data Usage Page (Generic Desktop) 05 01 Usage (Multi-Axis Controller) 09 08 Collection (Application) A1 01 Collection (Physical) A1 00 Report ID (1) 85 01 Logical Minimum (-500) 16 0C FE Logical Maximum (500) 26 F4 01 Physical Minimum (-32768) 36 00 80 Physical Maximum (32767) 46 FF 7F Usage (X) 09 30 Usage (Y) 09 31 Usage (Z) 09 32 Report Size (16) 75 10 Report Count (3) 95 03 Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02 End Collection C0 If I try this, it works fine: __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x08, //Usage (Multi-Axis Controller) 0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x00, // Collection (Physical) 0x85, 0x01, // Report ID (1) 0x16,0x0c,0xfe, // Logical minimum (-500) 0x26,0xf4,0x01, // Logical maximum (500) 0x35,0x00, // Physical Minimum (0) 0x46,0xff,0x00, // Physical Maximum (255) 0x09,0x30, // Usage(X) 0x09,0x31, // Usage(Y) 0x09,0x32, // Usage(Z) 0x09,0x33, // Usage(RX) 0x09,0x34, // Usage(RY) 0x09,0x35, // //Usage(RZ) 0x75, 0x08, // REPORT_SIZE (16) 0x95, 0x06, // REPORT_COUNT (6) 0x81, 0x02, // INPUT (Data,Var,Abs,Vol) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; But if I try the same descriptor that my 3D mouse: __ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = { 0x05, 0x01, // Usage Page (Generic Desktop) 0x09, 0x08, // Usage (Multi-Axis Controller) 0xa1, 0x01, // COLLECTION (Application) 0xa1, 0x00, // Collection (Physical) 0x85, 0x01, // Report ID (1) 0x16,0x0c,0xfe, // Logical minimum (-500) 0x26,0xf4,0x01, // Logical maximum (500) 0x35,0x00,0x80, // Physical Minimum (-32768) 0x46,0xff,0x7f, // Physical Maximum (32767) 0x09,0x30, // Usage(X) 0x09,0x31, // Usage(Y) 0x09,0x32, // Usage(Z) 0x75, 0x10, // REPORT_SIZE (16) 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x02, // INPUT (Data,Var,Abs,Vol) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; Windows gives me the same error, and it can't start the device!!! What is wrong? Do I need a special driver for Windows to send 32 bit data (int32)? For information, I use the HID library for my application PC side. How can I resolve this?
The LOGICAL_MAXIMUM four-byte descriptor tag (0x27) is only valid up to 0x7FFFFFFF as it is describing a maximum for a signed int data field. If you want to describe an unsigned int data field you would need to use the LOGICAL_MAXIMUM 8 byte descriptor tag like this: 0x28, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 Your second example would work, I think. Except for the typo for the Physical maximum descriptor tag. It should be 0x36, not 0x35.
When I tried your last descriptor (using my Arduino USBComposite library for STM32F1), Windows gave me an error about the descriptor having an unknown item. But when I changed the 0x35 in the Physical Minimum line to 0x36, Windows recognized the item.
Enable RTS pin on Beaglebone Black UART1
I want to use RTS pin of UART1 to communicate through RS 485 protocol. I have enabled UART1 through /media/BEAGLEBONE/uEnv.txt optargs=quiet drm.debug=7 capemgr.enable_partno=BB-UART1 Device tree overlay snippet: 0x180 0x20 /* uart1_rxd | MODE0 */ 0x184 0x20 /* uart1_txd | MODE0 */ 0x17c 0x00 /* uart1_rts | MODE0 */ 0x178 0x00 /* uart1_cts | MODE0 */ cat /proc/tty/driver/OMAP-SERIAL serinfo:1.0 driver revision: 0: uart:OMAP UART0 mmio:0x44E09000 irq:72 tx:2818 rx:100 RTS|CTS|DTR|DSR 1: uart:OMAP UART1 mmio:0x48022000 irq:73 tx:0 rx:0 CTS|DSR|CD|RI How to enable RTS pin on P9.19 by selecting mode 0 ?
The muxing mode of the pins both set to same mode. Change it to: 0x180 0x20 /* UART1_RXD, INPUT | MODE0 */ 0x184 0x00 /* UART1_TXD, OUTPUT | MODE0 */ 0x17c 0x00 /*UART1_RTS*/ 0x178 0x20 /*UART1_CTS*/ To use the RTS pin send the pin number from the overlay. rts-gpio = <&gpio0 13 0>