cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC Host SetControlLineState

simon239955_stm1_st
Associate II

Hi

Can anyone please show me an example of a working USB CDC Host sending the SetControlLineState command? This hasn't been implemented in the STM32 HAL drivers/middleware but it should be a simple thing to add.

SetControlLineState is used to signal the Host is ready to receive data from the CDC device. I tried adding and calling my own routine after the USB enumeration completes:

USBH_StatusTypeDef  USBH_CDC_SetControlLineState(USBH_HandleTypeDef *phost)
{
 
  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | USB_REQ_RECIPIENT_INTERFACE;
	
  phost->Control.setup.b.bRequest = CDC_SET_CONTROL_LINE_STATE;
  phost->Control.setup.b.wValue.w = 3U;
  phost->Control.setup.b.wIndex.w = 2;
  phost->Control.setup.b.wLength.w = 0;
 
  return USBH_CtlReq(phost, 0, 0);
}

The transmitted data appears to be correctly formed but the phost->RequestState appears to get stuck on CMD_WAIT expecting a reply from the device which I understand is not part of the CDC protocol. I then modified USBH_CtlReq to always set phost->RequestState = CMD_SEND when called from the above procedure but I still cannot get the USB CDC device to send data out.

I would be gratedul for a working USB CDC Host SetControlLineState example or suggestions to try.

Thank you in advance.

3 REPLIES 3
bernieserver
Associate II

Hi ST,

I am waiting as well for exaktly the same feature or I am looking for a way to set the DTR signal on an USB device.

BAW
Associate III

Was there any solution to this?

I am using the STM32407 discovery board in USB CDC Host mode and am trying to communicate with another MCU in USB CDC ACM Device mode. The other MCU works fine when connecting to a PC and can see that the DTR signal is being sent.

I am not sure how to do this on the STM32 side since it is not implemented in the stack?

 

 

 

This is how I implemented the function to send DTR from USB CDC HOST to a USB CDC DEVICE.

The host for me is an stm32G0 and the device is a nRF52840.
In my specific case, the usb device was not responding to anything I sent, so I the FIRST thing I had to send was the DTR signal, and then it worked fine.

#define DTR 0x01

USBH_StatusTypeDef usbh_cdc_set_dtr(USBH_HandleTypeDef *phost)
{
  phost->Control.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS |
                                         USB_REQ_RECIPIENT_INTERFACE;

  phost->Control.setup.b.bRequest = CDC_SET_CONTROL_LINE_STATE;

  phost->Control.setup.b.wValue.w = DTR;

  phost->Control.setup.b.wIndex.w = 0U;

  phost->Control.setup.b.wLength.w = 0U;

  return USBH_CtlReq(phost, NULL, 0);
}

 
This is the a simple example how it can be used (just to paint the picture, I recommend designing the logic better)

  while (Appli_state != APPLICATION_READY);

  USBH_StatusTypeDef status;
  do
  {
    status = usbh_cdc_set_dtr(&hUsbHostFS);
  }
  while (status != USBH_OK);

 
Basically, the request has to be sent when the Appli_state == APPLICATION_READY, since that means the CDC communication is ready.

If the usbh_cdc_set_dtr function is called only once it will return USBH_BUSY, so we have to keep calling it until it returns USBH_FAIL or USBH_OK, since the function USBH_CtlReq was designed to be non blocking.