|
|
|
@ -12,7 +12,7 @@ |
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
/** @brief library for USB CDC ACM communication (code)
|
|
|
|
|
/** library for USB CDC ACM communication (code)
|
|
|
|
|
* @file usb_cdcacm.c |
|
|
|
|
* @author King Kévin <kingkevin@cuvoodoo.info> |
|
|
|
|
* @date 2016 |
|
|
|
@ -36,7 +36,7 @@ |
|
|
|
|
#include "global.h" // global utilities |
|
|
|
|
#include "usb_cdcacm.h" // USB CDC ACM header and definitions |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM device descriptor
|
|
|
|
|
/** USB CDC ACM device descriptor
|
|
|
|
|
* @note as defined in USB CDC specification section 5 |
|
|
|
|
*/ |
|
|
|
|
static const struct usb_device_descriptor device_descriptor = { |
|
|
|
@ -56,7 +56,7 @@ static const struct usb_device_descriptor device_descriptor = { |
|
|
|
|
.bNumConfigurations = 1, // the number of possible configurations this device has
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM data endpoints
|
|
|
|
|
/** USB CDC ACM data endpoints
|
|
|
|
|
* @note as defined in USB CDC specification section 5 |
|
|
|
|
*/ |
|
|
|
|
static const struct usb_endpoint_descriptor data_endpoints[] = {{ |
|
|
|
@ -75,7 +75,7 @@ static const struct usb_endpoint_descriptor data_endpoints[] = {{ |
|
|
|
|
.bInterval = 1, // the frequency, in number of frames, that we're going to be sending data
|
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM communication endpoints
|
|
|
|
|
/** USB CDC ACM communication endpoints
|
|
|
|
|
* @note This notification endpoint isn't implemented. According to CDC spec its optional, but its absence causes a NULL pointer dereference in Linux cdc_acm driver |
|
|
|
|
*/ |
|
|
|
|
static const struct usb_endpoint_descriptor communication_endpoints[] = {{ |
|
|
|
@ -87,7 +87,7 @@ static const struct usb_endpoint_descriptor communication_endpoints[] = {{ |
|
|
|
|
.bInterval = 255, // the frequency, in number of frames, that we're going to be sending data
|
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM functional descriptor
|
|
|
|
|
/** USB CDC ACM functional descriptor
|
|
|
|
|
* @return |
|
|
|
|
* @note as defined in USB CDC specification section 5.2.3 |
|
|
|
|
*/ |
|
|
|
@ -125,7 +125,7 @@ static const struct { |
|
|
|
|
}, |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC interface descriptor
|
|
|
|
|
/** USB CDC interface descriptor
|
|
|
|
|
* @note as defined in USB CDC specification section 5.1.3 |
|
|
|
|
*/ |
|
|
|
|
static const struct usb_interface_descriptor communication_interface[] = {{ |
|
|
|
@ -145,7 +145,7 @@ static const struct usb_interface_descriptor communication_interface[] = {{ |
|
|
|
|
.extralen = sizeof(cdcacm_functional_descriptors), |
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM data class interface descriptor
|
|
|
|
|
/** USB CDC ACM data class interface descriptor
|
|
|
|
|
* @note as defined in USB CDC specification section 5.1.3 |
|
|
|
|
*/ |
|
|
|
|
static const struct usb_interface_descriptor data_interface[] = {{ |
|
|
|
@ -162,7 +162,7 @@ static const struct usb_interface_descriptor data_interface[] = {{ |
|
|
|
|
.endpoint = data_endpoints, |
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM interface descriptor */ |
|
|
|
|
/** USB CDC ACM interface descriptor */ |
|
|
|
|
static const struct usb_interface interfaces[] = {{ |
|
|
|
|
.num_altsetting = 1, |
|
|
|
|
.altsetting = communication_interface, |
|
|
|
@ -171,7 +171,7 @@ static const struct usb_interface interfaces[] = {{ |
|
|
|
|
.altsetting = data_interface, |
|
|
|
|
}}; |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM configuration descriptor */ |
|
|
|
|
/** USB CDC ACM configuration descriptor */ |
|
|
|
|
static const struct usb_config_descriptor config = { |
|
|
|
|
.bLength = USB_DT_CONFIGURATION_SIZE, // the length of this header in bytes
|
|
|
|
|
.bDescriptorType = USB_DT_CONFIGURATION, // a value of 2 indicates that this is a configuration descriptor
|
|
|
|
@ -185,7 +185,7 @@ static const struct usb_config_descriptor config = { |
|
|
|
|
.interface = interfaces, // pointer to an array of interfaces
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** @brief USB string table
|
|
|
|
|
/** USB string table
|
|
|
|
|
* @note starting with index 1 |
|
|
|
|
*/ |
|
|
|
|
static const char *usb_strings[] = { |
|
|
|
@ -209,7 +209,7 @@ static volatile uint8_t tx_used = 0; /**< how much data needs to be transmitted |
|
|
|
|
mutex_t tx_lock = MUTEX_UNLOCKED; /**< lock to update tx_i or tx_used */ |
|
|
|
|
volatile uint8_t cdcacm_received = 0; // same as rx_used, but since the user can write this variable we don't rely on it
|
|
|
|
|
|
|
|
|
|
/** @brief disconnect USB by pulling down D+ to for re-enumerate */ |
|
|
|
|
/** disconnect USB by pulling down D+ to for re-enumerate */ |
|
|
|
|
static void usb_disconnect(void) |
|
|
|
|
{ |
|
|
|
|
/* short USB disconnect to force re-enumerate */ |
|
|
|
@ -233,7 +233,7 @@ static void usb_disconnect(void) |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief incoming USB CDC ACM control request
|
|
|
|
|
/** incoming USB CDC ACM control request
|
|
|
|
|
* @param[in] usbd_dev USB device descriptor |
|
|
|
|
* @param[in] req control request information |
|
|
|
|
* @param[in] buf control request data |
|
|
|
@ -292,7 +292,7 @@ static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data * |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM data received callback
|
|
|
|
|
/** USB CDC ACM data received callback
|
|
|
|
|
* @param[in] usbd_dev USB device descriptor |
|
|
|
|
* @param[in] ep endpoint where data came in |
|
|
|
|
*/ |
|
|
|
@ -314,7 +314,7 @@ static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief USB CDC ACM data transmitted callback
|
|
|
|
|
/** USB CDC ACM data transmitted callback
|
|
|
|
|
* @param[in] usbd_dev USB device descriptor |
|
|
|
|
* @param[in] ep endpoint where data came in |
|
|
|
|
*/ |
|
|
|
@ -339,7 +339,7 @@ static void cdcacm_data_tx_cb(usbd_device *usbd_dev, uint8_t ep) |
|
|
|
|
usbd_poll(usb_device); // ensure the data gets sent
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief set USB CDC ACM configuration
|
|
|
|
|
/** set USB CDC ACM configuration
|
|
|
|
|
* @param[in] usbd_dev USB device descriptor |
|
|
|
|
* @param[in] wValue not used |
|
|
|
|
*/ |
|
|
|
@ -407,7 +407,7 @@ void cdcacm_putchar(char c) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief USB interrupt service routine called when data is received */ |
|
|
|
|
/** USB interrupt service routine called when data is received */ |
|
|
|
|
void usb_lp_can_rx0_isr(void) { |
|
|
|
|
usbd_poll(usb_device); |
|
|
|
|
} |
|
|
|
|