Paparazzi UAS  v5.17_devel-14-g4575375
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
usb_ser_hw.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michal Podhradsky,
3  * based on example from libopencm3
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  *
22  */
23 
29 /* This version derived from libopencm3 example */
30 #include <stdlib.h>
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>
39 #include <libopencm3/stm32/otg_fs.h>
40 
41 #include "mcu_periph/usb_serial.h"
42 
43 #include "mcu_periph/sys_time_arch.h"
44 
45 /* Max packet size for USB transfer */
46 #define MAX_PACKET_SIZE 64
47 /* Max fifo size for storing data */
48 #define VCOM_FIFO_SIZE 256
49 
50 #define TX_TIMEOUT_CNT 20 //TODO, make dynamic with event period
51 
52 typedef struct {
53  int head;
54  int tail;
55  uint8_t *buf;
56 } fifo_t;
57 
60 
61 static fifo_t txfifo;
62 static fifo_t rxfifo;
63 
64 void fifo_init(fifo_t *fifo, uint8_t *buf);
65 bool fifo_put(fifo_t *fifo, uint8_t c);
66 bool fifo_get(fifo_t *fifo, uint8_t *pc);
67 bool fifo_peek(fifo_t *fifo, uint8_t *pc, uint8_t ofs);
68 int fifo_avail(fifo_t *fifo);
69 int fifo_free(fifo_t *fifo);
70 int tx_timeout; // tmp work around for usbd_ep_stall_get from, this function does not always seem to work
71 
72 usbd_device *my_usbd_dev;
73 
74 static const struct usb_device_descriptor dev = {
75  .bLength = USB_DT_DEVICE_SIZE,
76  .bDescriptorType = USB_DT_DEVICE,
77  .bcdUSB = 0x0200,
78  .bDeviceClass = USB_CLASS_CDC,
79  .bDeviceSubClass = 0,
80  .bDeviceProtocol = 0,
81  .bMaxPacketSize0 = MAX_PACKET_SIZE,
82  .idVendor = 0x1d50, // OpenMoko, Inc.
83  .idProduct = 0x603d, // Paparazzi LPC(STM32)USB Serial
84  .bcdDevice = 0x0200,
85  .iManufacturer = 1,
86  .iProduct = 2,
87  .iSerialNumber = 3,
88  .bNumConfigurations = 1,
89 };
90 
91 /*
92  * This notification endpoint isn't implemented. According to CDC spec it's
93  * optional, but its absence causes a NULL pointer dereference in the
94  * Linux cdc_acm driver.
95  */
96 static const struct usb_endpoint_descriptor comm_endp[] = {{
97  .bLength = USB_DT_ENDPOINT_SIZE,
98  .bDescriptorType = USB_DT_ENDPOINT,
99  .bEndpointAddress = 0x83,
100  .bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
101  .wMaxPacketSize = 16,
102  .bInterval = 255,
103  }
104 };
105 
106 static const struct usb_endpoint_descriptor data_endp[] = {{
107  .bLength = USB_DT_ENDPOINT_SIZE,
108  .bDescriptorType = USB_DT_ENDPOINT,
109  .bEndpointAddress = 0x01,
110  .bmAttributes = USB_ENDPOINT_ATTR_BULK,
111  .wMaxPacketSize = MAX_PACKET_SIZE,
112  .bInterval = 1,
113  }, {
114  .bLength = USB_DT_ENDPOINT_SIZE,
115  .bDescriptorType = USB_DT_ENDPOINT,
116  .bEndpointAddress = 0x82,
117  .bmAttributes = USB_ENDPOINT_ATTR_BULK,
118  .wMaxPacketSize = MAX_PACKET_SIZE,
119  .bInterval = 1,
120  }
121 };
122 
123 static const struct {
124  struct usb_cdc_header_descriptor header;
125  struct usb_cdc_call_management_descriptor call_mgmt;
126  struct usb_cdc_acm_descriptor acm;
127  struct usb_cdc_union_descriptor cdc_union;
128 } __attribute__((packed)) cdcacm_functional_descriptors = {
129  .header = {
130  .bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
131  .bDescriptorType = CS_INTERFACE,
132  .bDescriptorSubtype = USB_CDC_TYPE_HEADER,
133  .bcdCDC = 0x0110,
134  },
135  .call_mgmt = {
136  .bFunctionLength =
137  sizeof(struct usb_cdc_call_management_descriptor),
138  .bDescriptorType = CS_INTERFACE,
139  .bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
140  .bmCapabilities = 0,
141  .bDataInterface = 1,
142  },
143  .acm = {
144  .bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
145  .bDescriptorType = CS_INTERFACE,
146  .bDescriptorSubtype = USB_CDC_TYPE_ACM,
147  .bmCapabilities = 0,
148  },
149  .cdc_union = {
150  .bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
151  .bDescriptorType = CS_INTERFACE,
152  .bDescriptorSubtype = USB_CDC_TYPE_UNION,
153  .bControlInterface = 0,
154  .bSubordinateInterface0 = 1,
155  }
156 };
157 
158 static const struct usb_interface_descriptor comm_iface[] = {{
159  .bLength = USB_DT_INTERFACE_SIZE,
160  .bDescriptorType = USB_DT_INTERFACE,
161  .bInterfaceNumber = 0,
162  .bAlternateSetting = 0,
163  .bNumEndpoints = 1,
164  .bInterfaceClass = USB_CLASS_CDC,
165  .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
166  .bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
167  .iInterface = 0,
168 
169  .endpoint = comm_endp,
170 
172  .extralen = sizeof(cdcacm_functional_descriptors)
173  }
174 };
175 
176 static const struct usb_interface_descriptor data_iface[] = {{
177  .bLength = USB_DT_INTERFACE_SIZE,
178  .bDescriptorType = USB_DT_INTERFACE,
179  .bInterfaceNumber = 1,
180  .bAlternateSetting = 0,
181  .bNumEndpoints = 2,
182  .bInterfaceClass = USB_CLASS_DATA,
183  .bInterfaceSubClass = 0,
184  .bInterfaceProtocol = 0,
185  .iInterface = 0,
186 
187  .endpoint = data_endp,
188  }
189 };
190 
191 static const struct usb_interface ifaces[] = {{
192  .num_altsetting = 1,
193  .altsetting = comm_iface,
194  }, {
195  .num_altsetting = 1,
196  .altsetting = data_iface,
197  }
198 };
199 
200 static const struct usb_config_descriptor config = {
201  .bLength = USB_DT_CONFIGURATION_SIZE,
202  .bDescriptorType = USB_DT_CONFIGURATION,
203  .wTotalLength = 0,
204  .bNumInterfaces = 2,
205  .bConfigurationValue = 1,
206  .iConfiguration = 0,
207  .bmAttributes = 0x80,
208  .bMaxPower = 0x32,
209 
210  .interface = ifaces,
211 };
212 
213 static char serial_no[25];
214 
215 /* Description of the device as it appears after enumeration */
216 static const char *usb_strings[] = {
217  "Paparazzi UAV",
218  "CDC Serial STM32",
219  serial_no,
220 };
221 
222 
223 /*
224  * Buffer to be used for control requests.
225  * (from libopencm3 examples)
226  */
228 
233 static int cdcacm_control_request(usbd_device *usbd_dev, struct usb_setup_data *req, uint8_t **buf,
234  uint16_t *len, void (**complete)(usbd_device *usbd_dev, struct usb_setup_data *req))
235 {
236  (void)complete;
237  (void)buf;
238  (void)usbd_dev;
239 
240  switch (req->bRequest) {
241  case USB_CDC_REQ_SET_CONTROL_LINE_STATE: {
242  /*
243  * This Linux cdc_acm driver requires this to be implemented
244  * even though it's optional in the CDC spec, and we don't
245  * advertise it in the ACM functional descriptor.
246  */
247  char local_buf[10];
248  struct usb_cdc_notification *notif = (void *)local_buf;
249 
250  /* We echo signals back to host as notification. */
251  notif->bmRequestType = 0xA1;
252  notif->bNotification = USB_CDC_NOTIFY_SERIAL_STATE;
253  notif->wValue = 0;
254  notif->wIndex = 0;
255  notif->wLength = 2;
256  local_buf[8] = req->wValue & 3;
257  local_buf[9] = 0;
258  usbd_ep_write_packet(usbd_dev, 0x83, local_buf, 10);
259  return 1;
260  }
261  case USB_CDC_REQ_SET_LINE_CODING:
262  if (*len < sizeof(struct usb_cdc_line_coding)) {
263  return 0;
264  }
265 
266  return 1;
267  default:
268  return 0;
269  }
270 }
271 
276 static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
277 {
278  (void)ep;
280  static int len = 0;
281  // read packet
282  len = usbd_ep_read_packet(usbd_dev, 0x01, buf, MAX_PACKET_SIZE);
283 
284  // write to fifo
285  for (int i = 0; i < len; i++) {
286  fifo_put(&rxfifo, buf[i]);
287  }
288 }
289 
290 // store USB connection status
291 static bool usb_connected;
292 
293 // use suspend callback to detect disconnect
294 static void suspend_cb(void)
295 {
296  usb_connected = false;
297 }
298 
303 static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
304 {
305  (void)wValue;
306 
307  usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, MAX_PACKET_SIZE, cdcacm_data_rx_cb);
308  usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, MAX_PACKET_SIZE, NULL);
309  usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
310 
311  usbd_register_control_callback(usbd_dev,
312  USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
313  USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
315 
316  // use config and suspend callback to detect connect
317  usb_connected = true;
318  usbd_register_suspend_callback(usbd_dev, suspend_cb);
319 }
320 
321 
322 void fifo_init(fifo_t *fifo, uint8_t *buf)
323 {
324  fifo->head = 0;
325  fifo->tail = 0;
326  fifo->buf = buf;
327 }
328 
329 
330 
331 bool fifo_put(fifo_t *fifo, uint8_t c)
332 {
333  int next;
334 
335  // check if FIFO has room
336  next = (fifo->head + 1) % VCOM_FIFO_SIZE;
337  if (next == fifo->tail) {
338  // full
339  return false;
340  }
341 
342  fifo->buf[fifo->head] = c;
343  fifo->head = next;
344 
345  return true;
346 }
347 
348 
349 bool fifo_get(fifo_t *fifo, uint8_t *pc)
350 {
351  int next;
352 
353  // check if FIFO has data
354  if (fifo->head == fifo->tail) {
355  return false;
356  }
357 
358  next = (fifo->tail + 1) % VCOM_FIFO_SIZE;
359 
360  *pc = fifo->buf[fifo->tail];
361  fifo->tail = next;
362 
363  return true;
364 }
365 
366 
367 int fifo_avail(fifo_t *fifo)
368 {
369  return (VCOM_FIFO_SIZE + fifo->head - fifo->tail) % VCOM_FIFO_SIZE;
370 }
371 
372 
373 int fifo_free(fifo_t *fifo)
374 {
375  return (VCOM_FIFO_SIZE - 1 - fifo_avail(fifo));
376 }
377 
378 bool fifo_peek(fifo_t *fifo, uint8_t *pc, uint8_t ofs) {
379  if (fifo_avail(fifo) < ofs + 1) {
380  return false;
381  }
382  int index = (fifo->tail + ofs) % VCOM_FIFO_SIZE;
383  *pc = fifo->buf[index];
384  return true;
385 }
386 
387 
397 int VCOM_putchar(int c)
398 {
399  if (usb_connected) {
400  // check if there are at least two more bytes left in queue
401  if (VCOM_check_free_space(2)) {
402  // if yes, add char
403  fifo_put(&txfifo, c);
404  /*c is not send until VCOM_send_message is called. This only happens in three cases:
405  * i) after a timeout (giving the chance to add more data to the fifo before sending)
406  * ii) if the fifo is filled, at which point the data is send immidiately
407  * iii) VCOM_send_message is called externally
408  */
409  tx_timeout = TX_TIMEOUT_CNT; // set timeout
410  } else {
411  // less than 2 bytes available, add byte and send data now
412  fifo_put(&txfifo, c);
413  sys_time_usleep(10); //far from optimal, increase fifo size to prevent this problem
415  }
416  return c;
417  }
418  return -1;
419 }
420 
425 int VCOM_getchar(void)
426 {
427  static int result = 0;
428  uint8_t c;
429  result = fifo_get(&rxfifo, &c) ? c : -1;
430  return result;
431 }
432 
438 int VCOM_peekchar(int ofs)
439 {
440  static int result = 0;
441  uint8_t c;
442  result = fifo_peek(&rxfifo, &c, ofs) ? c : -1;
443  return result;
444 }
445 
451 {
452  return (fifo_free(&txfifo) >= len ? TRUE : FALSE);
453 }
454 
460 {
461  return (fifo_avail(&rxfifo));
462 }
463 
468 void VCOM_event(void)
469 {
470  if (tx_timeout == 1) { // send any remaining bytes that still hang arround in the tx fifo, after a timeout
471  if (fifo_avail(&txfifo)) {
473  }
474  }
475  if (tx_timeout > 0) {
476  tx_timeout--;
477  }
478 
479  usbd_poll(my_usbd_dev);
480 
481 }
482 
488 {
489  if (usb_connected) {
490 
492  uint8_t i;
493  for (i = 0; i < MAX_PACKET_SIZE; i++) {
494  if (!fifo_get(&txfifo, &buf[i])) {
495  break;
496  }
497  }
498 
499  // wait until the line is free to write
500  // this however seems buggy, sometimes data gets lost even for the stall to clear
501  // so do not call this function continously without additional safe guards
502  while (usbd_ep_stall_get(my_usbd_dev, 0x82)) {};
503 
504  // send the data over usb
505  usbd_ep_write_packet(my_usbd_dev, 0x82, buf, i);
506 
507  }
508 }
509 
510 
511 /*
512  * USE_USB_LINE_CODING is not used in case of example1, example2 and telemetry
513  */
514 #ifdef USE_USB_LINE_CODING
515 void VCOM_allow_linecoding(uint8_t mode __attribute__((unused))) {}
516 void VCOM_set_linecoding(uint8_t mode __attribute__((unused))) {}
517 #endif
518 
519 /*
520  * For USB telemetry & generic device API
521  */
522 // Periph with generic device API
524 
525 // Functions for the generic device API
526 static int usb_serial_check_free_space(struct usb_serial_periph *p __attribute__((unused)),
527  long *fd __attribute__((unused)),
528  uint16_t len)
529 {
530  return (int)VCOM_check_free_space(len);
531 }
532 
533 static void usb_serial_transmit(struct usb_serial_periph *p __attribute__((unused)),
534  long fd __attribute__((unused)),
535  uint8_t byte)
536 {
537  VCOM_putchar(byte);
538 }
539 
540 static void usb_serial_transmit_buffer(struct usb_serial_periph *p __attribute__((unused)),
541  long fd __attribute__((unused)),
542  uint8_t *data, uint16_t len)
543 {
544  int i;
545  for (i = 0; i < len; i++) {
546  VCOM_putchar(data[i]);
547  }
548 }
549 
550 static void usb_serial_send(struct usb_serial_periph *p __attribute__((unused)), long fd __attribute__((unused)))
551 {
553 }
554 
555 static int usb_serial_char_available(struct usb_serial_periph *p __attribute__((unused)))
556 {
557  return VCOM_check_available();
558 }
559 
560 static uint8_t usb_serial_getch(struct usb_serial_periph *p __attribute__((unused)))
561 {
562  return (uint8_t)(VCOM_getchar());
563 }
564 
565 void VCOM_init(void)
566 {
567  // initialise fifos
568  fifo_init(&txfifo, txdata);
569  fifo_init(&rxfifo, rxdata);
570 
571  /* set up GPIO pins */
572 #if defined STM32F4
573  rcc_periph_clock_enable(RCC_GPIOA);
574  gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE,
575  GPIO11 | GPIO12);
576  gpio_set_af(GPIOA, GPIO_AF10, GPIO11 | GPIO12);
577 #endif
578 
579  /* USB clock */
580  rcc_periph_clock_enable(RCC_OTGFS);
581 
582  /* Get serial number */
583  desig_get_unique_id_as_string(serial_no, 25);
584 
585  /* usb driver init*/
586  my_usbd_dev = usbd_init(&otgfs_usb_driver, &dev, &config,
587  usb_strings, 3,
588  usbd_control_buffer, sizeof(usbd_control_buffer));
589 
590  usbd_register_set_config_callback(my_usbd_dev, cdcacm_set_config);
591 
592  // disable VBUS monitoring
593  OTG_FS_GCCFG = 0;
594  OTG_FS_GCCFG |= OTG_GCCFG_NOVBUSSENS | OTG_GCCFG_PWRDWN;
595 
596  // disconnected by default
597  usb_connected = false;
598 
599  // Configure generic device
600  usb_serial.device.periph = (void *)(&usb_serial);
601  usb_serial.device.check_free_space = (check_free_space_t) usb_serial_check_free_space;
602  usb_serial.device.put_byte = (put_byte_t) usb_serial_transmit;
603  usb_serial.device.put_buffer = (put_buffer_t) usb_serial_transmit_buffer;
604  usb_serial.device.send_message = (send_message_t) usb_serial_send;
605  usb_serial.device.char_available = (char_available_t) usb_serial_char_available;
606  usb_serial.device.get_byte = (get_byte_t) usb_serial_getch;
607 
608  tx_timeout = 0;
609 }
610 
unsigned short uint16_t
Definition: types.h:16
static bool usb_connected
Definition: usb_ser_hw.c:291
static const struct usb_interface_descriptor comm_iface[]
Definition: usb_ser_hw.c:158
#define GPIOA
Definition: gpio_arch.h:36
bool fifo_peek(fifo_t *fifo, uint8_t *pc, uint8_t ofs)
Definition: usb_ser_hw.c:378
static void cdcacm_set_config(usbd_device *usbd_dev, uint16_t wValue)
Set configuration and control callbacks for CDC device (from libopencm3 examples) ...
Definition: usb_ser_hw.c:303
#define MAX_PACKET_SIZE
Definition: usb_ser_hw.c:46
static uint8_t usb_serial_getch(struct usb_serial_periph *p)
Definition: usb_ser_hw.c:560
static void suspend_cb(void)
Definition: usb_ser_hw.c:294
int fifo_free(fifo_t *fifo)
Definition: usb_ser_hw.c:292
#define TX_TIMEOUT_CNT
Definition: usb_ser_hw.c:50
static char serial_no[25]
Definition: usb_ser_hw.c:213
static uint8_t rxdata[VCOM_FIFO_SIZE]
Definition: usb_ser_hw.c:59
static void cdcacm_data_rx_cb(usbd_device *usbd_dev, uint8_t ep)
RX callback for CDC device (from libopencm3 examples)
Definition: usb_ser_hw.c:276
void VCOM_send_message(void)
Definition: usb_ser_hw.c:574
void VCOM_event(void)
Definition: usb_ser_hw.c:571
static const struct @17 cdcacm_functional_descriptors
struct usb_serial_periph usb_serial
Definition: usb_ser_hw.c:547
static void usb_serial_transmit_buffer(struct usb_serial_periph *p, long fd, uint8_t *data, uint16_t len)
Definition: usb_ser_hw.c:540
static int usb_serial_check_free_space(struct usb_serial_periph *p, long *fd, uint16_t len)
Definition: usb_ser_hw.c:526
#define CS_INTERFACE
Definition: usb_ser_hw.c:78
uint8_t usbd_control_buffer[128]
Definition: usb_ser_hw.c:227
static const struct usb_endpoint_descriptor data_endp[]
Definition: usb_ser_hw.c:106
#define FALSE
Definition: std.h:5
void fifo_init(fifo_t *fifo, U8 *buf)
Definition: usb_ser_hw.c:246
void sys_time_usleep(uint32_t us)
sys_time_usleep(uint32_t us)
Definition: sys_time_arch.c:95
#define TRUE
Definition: std.h:4
static void usb_serial_send(struct usb_serial_periph *p, long fd)
Definition: usb_ser_hw.c:550
int head
Definition: usb_ser_hw.c:91
struct link_device device
Generic device interface.
Definition: usb_serial.h:37
bool VCOM_check_free_space(uint16_t len)
Checks if buffer free in VCOM buffer.
Definition: usb_ser_hw.c:409
int VCOM_getchar(void)
Reads one character from VCOM port.
Definition: usb_ser_hw.c:386
static const char * usb_strings[]
Definition: usb_ser_hw.c:216
#define VCOM_FIFO_SIZE
Definition: usb_ser_hw.c:48
uint8_t * buf
Definition: usb_ser_hw.c:93
#define GPIO_AF10
Definition: gpio_def.h:74
static fifo_t txfifo
Definition: usb_ser_hw.c:61
int fifo_avail(fifo_t *fifo)
Definition: usb_ser_hw.c:287
static const struct usb_device_descriptor dev
Definition: usb_ser_hw.c:74
int tx_timeout
Definition: usb_ser_hw.c:70
unsigned char uint8_t
Definition: types.h:14
int tail
Definition: usb_ser_hw.c:92
usbd_device * my_usbd_dev
Definition: usb_ser_hw.c:72
static uint8_t mode
mode holds the current sonar mode mode = 0 used at high altitude, uses 16 wave patterns mode = 1 used...
Definition: sonar_bebop.c:69
#define byte
BOOL fifo_put(fifo_t *fifo, U8 c)
Definition: usb_ser_hw.c:253
static const struct usb_config_descriptor config
Definition: usb_ser_hw.c:200
static void usb_serial_transmit(struct usb_serial_periph *p, long fd, uint8_t byte)
Definition: usb_ser_hw.c:533
int fd
Definition: serial.c:26
static const struct usb_endpoint_descriptor comm_endp[]
Definition: usb_ser_hw.c:96
void VCOM_set_linecoding(uint8_t mode)
static float p[2][2]
#define GPIO11
Definition: gpio_def.h:42
int VCOM_putchar(int c)
Writes one character to VCOM port.
Definition: usb_ser_hw.c:376
static const struct usb_interface ifaces[]
Definition: usb_ser_hw.c:191
static fifo_t rxfifo
Definition: usb_ser_hw.c:62
static int usb_serial_char_available(struct usb_serial_periph *p)
Definition: usb_ser_hw.c:555
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)
Definition: usb_ser_hw.c:233
#define GPIO12
Definition: gpio_def.h:43
BOOL fifo_get(fifo_t *fifo, U8 *pc)
Definition: usb_ser_hw.c:270
void VCOM_allow_linecoding(uint8_t mode)
int VCOM_peekchar(int ofs)
Reads one character from VCOM port without removing it from the queue.
Definition: usb_ser_hw.c:438
static uint8_t txdata[VCOM_FIFO_SIZE]
Definition: usb_ser_hw.c:58
int VCOM_check_available(void)
Checks if data available in VCOM buffer.
Definition: usb_ser_hw.c:420
void VCOM_init(void)
Definition: usb_ser_hw.c:586
arch independent USB API
static const struct usb_interface_descriptor data_iface[]
Definition: usb_ser_hw.c:176