USB: provide connectivity flag

This commit is contained in:
King Kévin 2018-02-23 15:59:28 +01:00
parent 721e181f15
commit b3bfcf9e77
2 changed files with 15 additions and 8 deletions

View File

@ -39,6 +39,8 @@
/** maximum packet size for USB data transfer */
#define USB_DATA_TRANSFER_SIZE 64
volatile bool usb_cdcacm_connecting = false;
static uint8_t usbd_control_buffer[128] = {0}; /**< buffer to be used for control requests */
static usbd_device *usb_device = NULL; /**< structure holding all the info related to the USB device */
@ -47,7 +49,6 @@ static uint8_t tx_buffer[512] = {0}; /**< ring buffer for data to transmit */
static volatile uint16_t tx_i = 0; /**< current position if transmitted data */
static volatile uint16_t tx_used = 0; /**< how much data needs to be transmitted */
static volatile bool tx_lock = false; /**< if the transmit buffer is currently being written */
static bool connected = false; /**< is the USB device is connected to a host */
/** USB CDC ACM device descriptor
* @note as defined in USB CDC specification section 5
@ -200,6 +201,7 @@ static const struct usb_interface_descriptor usb_dfu_interface = {
.bInterfaceSubClass = 1, /**< DFU interface subclass (not defined in libopencm3 dfu lib) */
.bInterfaceProtocol = 1, /**< runtime protocol (not defined in libopencm3 dfu lib) */
.iInterface = 3, /**< the index of the string in the string table that represents interface description */
.extra = &usb_dfu_functional, /**< point to functional descriptor */
.extralen = sizeof(usb_dfu_functional), /**< size of functional descriptor */
};
@ -324,7 +326,7 @@ static int usb_cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_da
} else {
switch (req->bRequest) {
case USB_CDC_REQ_SET_CONTROL_LINE_STATE:
connected = req->wValue ? true : false; // check if terminal is open
usb_cdcacm_connecting = req->wValue ? true : false; // check if terminal is open
//bool dtr = (req->wValue & (1 << 0)) ? true : false;
//bool rts = (req->wValue & (1 << 1)) ? true : false;
/* this Linux cdc_acm driver requires this to be implemented
@ -360,6 +362,9 @@ static int usb_cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_da
default:
return 0;
}
if (tx_used>0) { // if buffer is not empty
usbd_ep_write_packet(usb_device, 0x82, NULL, 0); // trigger tx callback
}
}
return 1;
}
@ -378,7 +383,7 @@ static void usb_cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
/* receive data */
usb_length = usbd_ep_read_packet(usbd_dev, 0x02, usb_data, sizeof(usb_data));
if (usb_length) { // copy received data
for (uint16_t i=0; i<usb_length; i++) { // only until buffer is full
for (uint16_t i=0; i<usb_length && i<LENGTH(usb_data); i++) { // only until buffer is full
user_input_store(usb_data[i]); // store user data
}
}
@ -393,7 +398,7 @@ static void usb_cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep)
(void)ep;
(void)usbd_dev;
if (!usbd_dev || !connected || !tx_used) { // verify if we can send and there is something to send
if (!usbd_dev || 0==tx_used) { // verify if we can send and there is something to send
return;
}
if (!tx_lock) {
@ -425,8 +430,6 @@ static void usb_cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
void usb_cdcacm_setup(void)
{
connected = false; // start with USB not connected
// initialize USB
rcc_periph_reset_pulse(RST_USB); // reset USB peripheral
usb_disconnect(); // disconnect to force re-enumeration
@ -440,11 +443,12 @@ void usb_cdcacm_setup(void)
tx_i = 0;
tx_used = 0;
tx_lock = false; // release lock
usb_cdcacm_connecting = false; // clear flag
}
void usb_cdcacm_putchar(char c)
{
if (!usb_device || !connected) {
if (!usb_device) {
return;
}
tx_lock = true; // put lock on transmit buffer
@ -456,7 +460,7 @@ void usb_cdcacm_putchar(char c)
tx_buffer[(tx_i+tx_used)%LENGTH(tx_buffer)] = c; // overwrite old data
}
tx_lock = false; // release lock on transmit buffer
if (tx_used>0) { // to buffer is not empty anymore
if (tx_used>0) { // if buffer is not empty anymore
usbd_ep_write_packet(usb_device, 0x82, NULL, 0); // trigger tx callback
}
}

View File

@ -19,6 +19,9 @@
*/
#pragma once
/** flag set to true when user is connected to USB CDC ACM port (e.g. when a terminal is opened) */
extern volatile bool usb_cdcacm_connecting;
/** setup USB CDC ACM peripheral */
void usb_cdcacm_setup(void);
/** send character over USB (non-blocking)