31 #include <libopencm3/stm32/rcc.h>
32 #include <libopencm3/stm32/gpio.h>
33 #include <libopencm3/cm3/nvic.h>
34 #include <libopencm3/cm3/systick.h>
35 #include <libopencm3/usb/usbd.h>
36 #include <libopencm3/usb/cdc.h>
37 #include <libopencm3/cm3/scb.h>
38 #include <libopencm3/stm32/desig.h>
44 #define MAX_PACKET_SIZE 64
46 #define VCOM_FIFO_SIZE 128
69 static const struct usb_device_descriptor
dev = {
70 .bLength = USB_DT_DEVICE_SIZE,
71 .bDescriptorType = USB_DT_DEVICE,
73 .bDeviceClass = USB_CLASS_CDC,
83 .bNumConfigurations = 1,
91 static const struct usb_endpoint_descriptor
comm_endp[] = {{
92 .bLength = USB_DT_ENDPOINT_SIZE,
93 .bDescriptorType = USB_DT_ENDPOINT,
94 .bEndpointAddress = 0x83,
95 .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
101 static const struct usb_endpoint_descriptor
data_endp[] = {{
102 .bLength = USB_DT_ENDPOINT_SIZE,
103 .bDescriptorType = USB_DT_ENDPOINT,
104 .bEndpointAddress = 0x01,
105 .bmAttributes = USB_ENDPOINT_ATTR_BULK,
109 .bLength = USB_DT_ENDPOINT_SIZE,
110 .bDescriptorType = USB_DT_ENDPOINT,
111 .bEndpointAddress = 0x82,
112 .bmAttributes = USB_ENDPOINT_ATTR_BULK,
118 static const struct {
119 struct usb_cdc_header_descriptor header;
120 struct usb_cdc_call_management_descriptor call_mgmt;
121 struct usb_cdc_acm_descriptor acm;
122 struct usb_cdc_union_descriptor cdc_union;
125 .bFunctionLength =
sizeof(
struct usb_cdc_header_descriptor),
127 .bDescriptorSubtype = USB_CDC_TYPE_HEADER,
132 sizeof(
struct usb_cdc_call_management_descriptor),
134 .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
139 .bFunctionLength =
sizeof(
struct usb_cdc_acm_descriptor),
141 .bDescriptorSubtype = USB_CDC_TYPE_ACM,
145 .bFunctionLength =
sizeof(
struct usb_cdc_union_descriptor),
147 .bDescriptorSubtype = USB_CDC_TYPE_UNION,
148 .bControlInterface = 0,
149 .bSubordinateInterface0 = 1,
153 static const struct usb_interface_descriptor
comm_iface[] = {{
154 .bLength = USB_DT_INTERFACE_SIZE,
155 .bDescriptorType = USB_DT_INTERFACE,
156 .bInterfaceNumber = 0,
157 .bAlternateSetting = 0,
159 .bInterfaceClass = USB_CLASS_CDC,
160 .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
161 .bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
171 static const struct usb_interface_descriptor
data_iface[] = {{
172 .bLength = USB_DT_INTERFACE_SIZE,
173 .bDescriptorType = USB_DT_INTERFACE,
174 .bInterfaceNumber = 1,
175 .bAlternateSetting = 0,
177 .bInterfaceClass = USB_CLASS_DATA,
178 .bInterfaceSubClass = 0,
179 .bInterfaceProtocol = 0,
186 static const struct usb_interface
ifaces[] = {{
195 static const struct usb_config_descriptor
config = {
196 .bLength = USB_DT_CONFIGURATION_SIZE,
197 .bDescriptorType = USB_DT_CONFIGURATION,
200 .bConfigurationValue = 1,
202 .bmAttributes = 0x80,
229 uint16_t *len,
void (**complete)(usbd_device *usbd_dev,
struct usb_setup_data *req))
235 switch (req->bRequest) {
236 case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
243 struct usb_cdc_notification *notif = (
void *)local_buf;
246 notif->bmRequestType = 0xA1;
247 notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
251 local_buf[8] = req->wValue & 3;
253 usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
256 case USB_CDC_REQ_SET_LINE_CODING:
257 if (*len <
sizeof(
struct usb_cdc_line_coding)) {
280 for (
int i = 0; i < len; i++) {
291 usb_connected =
FALSE;
303 usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK,
MAX_PACKET_SIZE, NULL);
304 usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
306 usbd_register_control_callback(usbd_dev,
307 USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
308 USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
312 usb_connected =
TRUE;
313 usbd_register_suspend_callback(usbd_dev,
suspend_cb);
332 if (next == fifo->
tail) {
406 static int result = 0;
408 result =
fifo_get(&rxfifo, &c) ? c : -1;
461 #ifdef USE_USB_LINE_CODING
507 gpio_mode_setup(
GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
513 rcc_periph_clock_enable(RCC_OTGFS);
516 desig_get_unique_id_as_string(serial_no, 25);
521 usbd_control_buffer,
sizeof(usbd_control_buffer));
526 usb_connected =
FALSE;
put_byte_t put_byte
put one byte
static const struct usb_interface_descriptor comm_iface[]
static int usb_serial_check_free_space(struct usb_serial_periph *p, uint8_t len)
uint8_t(* get_byte_t)(void *)
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
Set configuration and control callbacks for CDC device (from libopencm3 examples) ...
static uint8_t usb_serial_getch(struct usb_serial_periph *p)
static void suspend_cb(void)
check_free_space_t check_free_space
check if transmit buffer is not full
static char serial_no[25]
static uint8_t rxdata[VCOM_FIFO_SIZE]
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
RX callback for CDC device (from libopencm3 examples)
void VCOM_send_message(void)
struct usb_serial_periph usb_serial
uint8_t usbd_control_buffer[128]
static const struct usb_endpoint_descriptor data_endp[]
int fifo_free(fifo_t *fifo)
void * periph
pointer to parent implementation
void fifo_init(fifo_t *fifo, U8 *buf)
struct link_device device
Generic device interface.
static bool_t usb_connected
int VCOM_getchar(void)
Reads one character from VCOM port.
static const char * usb_strings[]
static void usb_serial_transmit(struct usb_serial_periph *p, uint8_t byte)
get_byte_t get_byte
get a new char
int(* char_available_t)(void *)
static const struct @10 cdcacm_functional_descriptors
static const struct usb_device_descriptor dev
void(* put_byte_t)(void *, uint8_t)
static void usb_serial_send(struct usb_serial_periph *p)
usbd_device * my_usbd_dev
BOOL fifo_put(fifo_t *fifo, U8 c)
static const struct usb_config_descriptor config
void(* send_message_t)(void *)
static const struct usb_endpoint_descriptor comm_endp[]
void VCOM_set_linecoding(uint8_t mode)
struct mavlink_msg_req req
int(* check_free_space_t)(void *, uint8_t)
Function pointers definition.
char_available_t char_available
check if a new character is available
int VCOM_putchar(int c)
Writes one character to VCOM port.
static const struct usb_interface ifaces[]
static int usb_serial_char_available(struct usb_serial_periph *p)
bool_t VCOM_check_free_space(uint8_t len)
Checks if buffer free in VCOM buffer.
static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf, uint16_t *len, void(**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
CDC device control request (from libopencm3 examples)
int fifo_avail(fifo_t *fifo)
BOOL fifo_get(fifo_t *fifo, U8 *pc)
void VCOM_allow_linecoding(uint8_t mode)
static uint8_t txdata[VCOM_FIFO_SIZE]
int VCOM_check_available(void)
Checks if data available in VCOM buffer.
send_message_t send_message
send completed buffer
static const struct usb_interface_descriptor data_iface[]