cancel
Showing results for 
Search instead for 
Did you mean: 

USB CDC - When does the endpoint become ready?

work
Associate II
Posted on February 10, 2016 at 10:49

Hi,

I'm using the CDC class driver version 2.4.1 and made the following changes to the usbd_cdc_if.c template:

Since the provided CDC_Transmit_FS function tries to transmit the packet forever, i.e.

do {

    result = USBD_CDC_TransmitPacket(hUsbDevice_0);

}

while(result != USBD_OK);

this function blocks if the endpoint is not ready. Hence, I added a USB_Ready flag, which is set at the end of CDC_Init_FS and unset in CDC_DeInit_FS. In case the flag is unset, CDC_Transmit_FS returns immediately (with USBD_FAIL return code).

Now I made a strange observation: I'm calling CDC_Transmit_FS from a high frequency loop. During the first iterations the transmit function fails, that's okay (I think). However, as soon as the ready flag is set, the first packet transmitted causes a call to CDC_Receive_FS with exactly the data I tried to send, while it actually never gets transmitted to the USB host. Therefore, I assume I try to send the data a bit too early. Does this makes sense to you? Is there a way to solve this problem?

#stm32-usb-cdc-vcp
3 REPLIES 3
work
Associate II
Posted on February 10, 2016 at 15:10

I found the solution:

The CDC_Init_FS function was the wrong place to wait. Instead, one has to look for the CDC_SET_CONTROL_LINE_STATE command. It's just a pity that the wValue field of the USBD_SetupReqTypedef struct is not passed to the CDC_Control_FS function, since this tells you whether DTR (data terminal ready) is set or not. (Maybe an idea for the next release?)

Posted on May 22, 2017 at 17:00

just add 

bool CDC_IsConnected = ((USBD_HandleTypeDef*)hpcd_USB_OTG_FS.pData)->request.wValue & 0x01;

on the 

CDC_SET_CONTROL_LINE_STATE switch path. should do it

Posted on May 23, 2018 at 10:09

Sorry for posting to old thread, but for others searching for a solution,  this is what I did:

static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)

{

...

  case CDC_SET_CONTROL_LINE_STATE:

      {

          USBD_SetupReqTypedef * req = (USBD_SetupReqTypedef *)pbuf;

          if(req->wValue &0x0001 != 0)

          {

              // DTR is set...

          }

      }

    break;

...

}