USB: fix again too early data transfer

This commit is contained in:
King Kévin 2018-04-03 14:01:20 +02:00
parent 91e085d6a6
commit 9ddb85bdcb
1 changed files with 19 additions and 18 deletions

View File

@ -293,19 +293,6 @@ static void usb_dfu_detach(usbd_device *usbd_dev, struct usb_setup_data *req)
while (true); // wait for the reset to happen
}
/** USB CDC ACM control callback
* @note if transmission happens before the control setting is complete, Linux echoes back the data
* @param[in] usbd_dev USB device descriptor
* @param[in] req control request information
*/
static void usb_cdcacm_control_cb(usbd_device *usbd_dev, struct usb_setup_data *req)
{
first_connection |= (0!=req->wValue); // check if port has been opened (windows set the control line state before a terminal opens the port, but with value 0)
if (usbd_dev && tx_used>0 && !usb_tx_ongoing && first_connection) { // if buffer is not empty
usbd_ep_write_packet(usbd_dev, 0x82, NULL, 0); // trigger tx callback
}
}
/** incoming USB CDC ACM control request
* @param[in] usbd_dev USB device descriptor
* @param[in] req control request information
@ -334,10 +321,10 @@ static int usb_cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_da
default: // other requests are not supported
return 0;
}
} else {
} else if (usb_cdcacm_communication_interface.bInterfaceNumber==req->wIndex) { // check if request is for CDC
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
usb_cdcacm_connecting = (0!=req->wValue); // check if terminal is open
usb_cdcacm_connecting = (0!=req->wValue); // check if terminal is open (windows set the control line state before a terminal opens the port, but with value 0)
//bool dtr = (req->wValue & (1 << 0)) ? true : false;
//bool rts = (req->wValue & (1 << 1)) ? true : false;
/* the Linux cdc_acm driver requires this to be implemented
@ -354,8 +341,7 @@ static int usb_cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_da
notif->wLength = 2;
reply[8] = req->wValue & 3;
reply[9] = 0;
usbd_ep_write_packet(usbd_dev, 0x81, reply, LENGTH(reply)); // send the reply
*complete = usb_cdcacm_control_cb; // check state once reply is transmitted
usbd_ep_write_packet(usbd_dev, 0x81, reply, LENGTH(reply)); // send the reply from communication endpoint (we can't use the complete callback because we are not using the current control endpoint)
break;
case USB_CDC_REQ_SET_LINE_CODING:
// ignore if length is wrong
@ -378,6 +364,21 @@ static int usb_cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_da
return 1;
}
/** USB CDC ACM communication callback
* @note if transmission happens before the control setting is complete with a response form the communication endpoint, Linux echoes back the data
* @param[in] usbd_dev USB device descriptor
* @param[in] req control request information
*/
static void usb_cdcacm_communication_cb(usbd_device *usbd_dev, uint8_t ep)
{
(void)ep; // not used
first_connection |= usb_cdcacm_connecting; // check if port has been opened
if (usbd_dev && tx_used>0 && !usb_tx_ongoing && first_connection) { // if buffer is not empty
usbd_ep_write_packet(usbd_dev, 0x82, NULL, 0); // trigger tx callback
}
}
/** USB CDC ACM data received callback
* @note called when data has been received
* @param[in] usbd_dev USB device descriptor
@ -433,7 +434,7 @@ static void usb_cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
{
(void)wValue; // not used
usbd_ep_setup(usbd_dev, usb_cdcacm_communication_endpoints[0].bEndpointAddress, usb_cdcacm_communication_endpoints[0].bmAttributes, usb_cdcacm_communication_endpoints[0].wMaxPacketSize, NULL); // set communication endpoint
usbd_ep_setup(usbd_dev, usb_cdcacm_communication_endpoints[0].bEndpointAddress, usb_cdcacm_communication_endpoints[0].bmAttributes, usb_cdcacm_communication_endpoints[0].wMaxPacketSize, usb_cdcacm_communication_cb); // set communication endpoint
usbd_ep_setup(usbd_dev, usb_cdcacm_data_endpoints[0].bEndpointAddress, usb_cdcacm_data_endpoints[0].bmAttributes, usb_cdcacm_data_endpoints[0].wMaxPacketSize, usb_cdcacm_data_rx_cb); // set outgoing (from host) data endpoint
usbd_ep_setup(usbd_dev, usb_cdcacm_data_endpoints[1].bEndpointAddress, usb_cdcacm_data_endpoints[1].bmAttributes, usb_cdcacm_data_endpoints[1].wMaxPacketSize, usb_cdcacm_data_tx_cb); // set incoming (to host) data endpoint