2021-09-28 02:26 AM
Hello,
I have to implement a USB CDC device that uses flow control. After a few research it seems to be possible to send a notification SERIAL_STATE that holds the signal DSR in its bitmap.
Also, I have found topics on this platform trying to answer this question:
None of which are helpful, #2 and #3 are closed without an answer, #1 and #4 seems to use the same code which does not work for me yet.
Based on example from #4, here is my code:
// usbd_cdc_if.h
typedef union
{
uint8_t val;
struct{
unsigned dcd :1;
unsigned dsr :1;
unsigned break_err :1;
unsigned ri :1;
unsigned frame_err :1;
unsigned parity_err :1;
unsigned overrun_err :1;
unsigned reserved :1;
};
} USBD_CDC_SerialStateTypeDef;
uint8_t CDC_Serial_State(USBD_CDC_SerialStateTypeDef serial_state);
// usbd_cdc_if.c
uint8_t CDC_Serial_State_Buf[10] = {
0xA1, // vmRequestType
0x20, // SERIAL_STATE
0x00, // wValue
0x00,
0x00, // wIndex
0x00,
0x02, // wLength
0x00,
0x00, // UART state bitmap
0x00,
};
/**
* @brief CDC_Serial_State
* Send SERIAL_STATE over USB IN interrupt endpoint through this function.
* @note
*
*
* @param serial_state: Uart State Bitmap Value
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Serial_State(USBD_CDC_SerialStateTypeDef serial_state)
{
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)&hUsbDeviceHS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
CDC_Serial_State_Buf[8] = serial_state.val;
hUsbDeviceHS.ep0_state = USBD_EP0_STATUS_IN;
hUsbDeviceHS.ep_in[0].total_length = 10;
hUsbDeviceHS.ep_in[0].rem_length = 10;
/* Start the transfer */
USBD_LL_Transmit (&hUsbDeviceHS, CDC_CMD_EP, CDC_Serial_State_Buf, 10);
return USBD_OK;
}
Now when calling CDC_Serial_State() the device seems to be stuck in the USB IRQ Handler and never returns from CDC_Serial_State().
What is the problem with this code? How am I supposed to send USB notifications?
Thanks for your support,
Morgan
2021-09-28 09:28 PM
Do you have an IN interrupt endpoint in your CDC control interface descriptor?
Do you see the host sending IN request to this endpoint?
2021-09-29 02:56 AM
Yes I do, from the STM32_USB_Device_Library I kept the default endpoints initialization:
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 2 Communications
bDeviceSubClass 2 Abstract (modem)
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0483 STMicroelectronics
idProduct 0x5740 Virtual COM Port
bcdDevice 2.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0043
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0xc0
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 2 Communications
bInterfaceSubClass 2 Abstract (modem)
bInterfaceProtocol 1 AT-commands (v.25ter)
iInterface 0
CDC Header:
bcdCDC 1.10
CDC Call Management:
bmCapabilities 0x00
bDataInterface 1
CDC ACM:
bmCapabilities 0x02
line coding and serial state
CDC Union:
bMasterInterface 0
bSlaveInterface 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 16
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 0
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
But I do not see the host sending request to this endpoint. By the way I monitor USB activity with Wireshark and usbmon.
Here is what I get from initialization, and then trying to send SERIAL STATE notification which is not seen :
No. Time Source Destination Protocol Length Info
1447 2.858586 host 3.17.0 USB 64 GET DESCRIPTOR Request DEVICE
1448 2.858787 3.17.0 host USB 82 GET DESCRIPTOR Response DEVICE
1451 2.858847 host 3.17.0 USB 64 GET DESCRIPTOR Request CONFIGURATION
1452 2.859007 3.17.0 host USB 73 GET DESCRIPTOR Response CONFIGURATION
1453 2.859023 host 3.17.0 USB 64 GET DESCRIPTOR Request CONFIGURATION
1454 2.859186 3.17.0 host USB 131 GET DESCRIPTOR Response CONFIGURATION
1455 2.859206 host 3.17.0 USB 64 GET DESCRIPTOR Request STRING
1456 2.859356 3.17.0 host USB 68 GET DESCRIPTOR Response STRING
1457 2.859367 host 3.17.0 USB 64 GET DESCRIPTOR Request STRING
1458 2.859533 3.17.0 host USB 108 GET DESCRIPTOR Response STRING
1459 2.859550 host 3.17.0 USB 64 GET DESCRIPTOR Request STRING
1460 2.859763 3.17.0 host USB 82 GET DESCRIPTOR Response STRING
1461 2.859770 host 3.17.0 USB 64 GET DESCRIPTOR Request STRING
1462 2.859917 3.17.0 host USB 90 GET DESCRIPTOR Response STRING
1463 2.862682 host 3.17.0 USB 64 SET CONFIGURATION Request
1464 2.862883 3.17.0 host USB 64 SET CONFIGURATION Response
1465 2.863011 host 3.17.0 USBCOM 71 SET LINE CODING Request
1466 2.863121 3.17.0 host USB 64 URB_CONTROL out
2023-04-28 02:25 AM
Hey,
I'm still a beginner at this. I have a couple of questions, what parameter to use when calling the CDC_Serial_State() function, it says "Uart State Bitmap Value", let's say I want to send a ri signal (ring signal), what will be the parameter in this case?
And did you figure out how to fix the problem of being stuck in the USB IRQ Handler?
2023-11-29 05:50 AM
Hello,
You succeeded implement a USB CDC device that uses flow control?
2023-11-29 07:36 AM
The notification is not implemented out-of-the-box in ST CDC. The notification should be sent via the interrupt in endpoint - in the example above it's 0x82 (not control EP 0/0x80). The notification packet content may be found in USB CDC class specification.
The overall program logic should be similar to that of a HID input device.
(My usual warning about ST USB): do NOT send anything from the main loop - USB transmit functions should only be called from an interrupt service routine of the same priority as USB hardware interrupt.
BTW do not specify protocol as 1 (AT commands) - it has some bad side effects.
2023-11-29 10:37 PM
I'm still a beginner at this. I don't really understand where to call CDC_Serial_State. Maybe you have a sample project? It would help me a lot to figure this out.
2024-01-10 09:01 PM
Hello.
As gbm mentioned, I introduced Serial_State into the periodic timer interrupt handler as well as the HID device.
However, it did not solve the problem of getting stuck in the IRQ handler as described in this topic.
The solution in the following topic was very helpful in solving this problem.
USB CDC device on STM32H750B-DK, problem with DTXFSTS register
In my case, the stack was caused by Fifo not being assigned.