USB CDC work only once w/ interupt endp - usb

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.

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

No data received form USB device

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.

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

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.

How to write entry into the System Event Log (SEL) via ipmitool?

I see in the ipmitool there is an "add" command in the sel menu. It wants a file, but what format for that file is it expecting?
> ipmitool sel add file.txt
> Invalid Event: 0000f8b601000000
From the doc: http://man.he.net/man1/ipmitool
add
Read event entries from a file and add them to the SEL.
New SEL entries area added onto the SEL after the last
record in the SEL. Record added is of type 2 and is
automatically timestamped.
The format of the file is the same as output by ipmitool sel save {filename} and looks like this:
0x04 0x10 0x07 0x6f 0x02 0xff 0xff # Event Logging Disabled #0x07 Log area reset/cleared
0x04 0x12 0x83 0x6f 0x05 0x00 0xff # System Event #0x83 Timestamp Clock Sync
0x04 0x12 0x83 0x6f 0x05 0x80 0xff # System Event #0x83 Timestamp Clock Sync
0x04 0x09 0x01 0x6f 0x00 0xff 0xff # Power Unit #0x01 Power off/down
0x04 0x09 0x01 0xef 0x00 0xff 0xff # Power Unit #0x01 Power off/down
0x04 0x14 0x09 0x6f 0x00 0xff 0xff # Button #0x09 Power Button pressed
Loading this into the SEL will log events with the current date/time.
Compare output of ipmitool sel save {filename} with ipimitool sel writeraw {filename} to determine the byte mapping above.