Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
usb_ser_hw.c
Go to the documentation of this file.
1 /*
2  ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
3  2011,2012 Giovanni Di Sirio.
4 
5  This file is part of ChibiOS/RT.
6 
7  ChibiOS/RT 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 3 of the License, or
10  (at your option) any later version.
11 
12  ChibiOS/RT is distributed in the hope that it will be ueful,
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 this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 
22 
23 #include <stdio.h>
24 #include <string.h>
25 #include "ch.h"
26 #include "hal.h"
27 #include "hal_serial_usb.h"
28 #include "mcu_periph/usb_serial.h"
29 
30 #if HAL_USE_SERIAL_USB
31 
32 #ifndef SERIAL_USB
33 #define SERIAL_USB USBD1
34 #endif
35 
39 #ifndef USBD1_DATA_REQUEST_EP
40 #define USBD1_DATA_REQUEST_EP 1
41 #endif
42 #ifndef USBD1_DATA_AVAILABLE_EP
43 #define USBD1_DATA_AVAILABLE_EP 1
44 #endif
45 #ifndef USBD1_INTERRUPT_REQUEST_EP
46 #define USBD1_INTERRUPT_REQUEST_EP 2
47 #endif
48 
52 #define USB_NUM_INTERFACES 2
53 #define USB_CDC_CIF_NUM0 0
54 #define USB_CDC_DIF_NUM0 1
55 
56 
57 //------------------------------ 2 serial USB --------------------------
58 #if USBD_NUMBER >= 2
59 #ifndef USBD2_DATA_REQUEST_EP
60 #define USBD2_DATA_REQUEST_EP 3
61 #endif
62 #ifndef USBD2_DATA_AVAILABLE_EP
63 #define USBD2_DATA_AVAILABLE_EP 3
64 #endif
65 #ifndef USBD2_INTERRUPT_REQUEST_EP
66 #define USBD2_INTERRUPT_REQUEST_EP 4
67 #endif
68 #undef USB_NUM_INTERFACES
69 #define USB_NUM_INTERFACES 4
70 #define USB_CDC_CIF_NUM1 2
71 #define USB_CDC_DIF_NUM1 3
72 #endif
73 
74 
75 #define USB_INTERRUPT_REQUEST_SIZE 0x10
76 #define USB_DATA_SIZE 0x40
77 
78 
79 
80 #if (CH_KERNEL_MAJOR == 2)
81  static EventListener inputAvailEL = {NULL, NULL, 0, 0};
82 #else
83  static event_listener_t inputAvailEL = {NULL, NULL, 0, 0, 0};
84 #endif
85 /*===========================================================================*/
86 /* USB related stuff. */
87 /*===========================================================================*/
88 
89 
90 
91 /*
92  * USB Device Descriptor.
93  */
94 static const uint8_t vcom_device_descriptor_data[18] = {
95  USB_DESC_DEVICE (0x0200, /* bcdUSB (1.1). */
96  0xEF, /* bDeviceClass (misc). */
97  0x02, /* bDeviceSubClass (common). */
98  0x01, /* bDeviceProtocol (IAD). */
99  USB_DATA_SIZE, /* bMaxPacketSize. */
100  0x0483, /* idVendor (ST). */
101  0x5740, /* idProduct. */
102  0x0200, /* bcdDevice. */
103  1, /* iManufacturer. */
104  2, /* iProduct. */
105  3, /* iSerialNumber. */
106  1) /* bNumConfigurations. */
107 };
108 
109 
110 /*
111  * Device Descriptor wrapper.
112  */
113 static const USBDescriptor vcom_device_descriptor = {
114  sizeof vcom_device_descriptor_data,
115  vcom_device_descriptor_data
116 };
117 
118 #define CDC_IF_DESC_SET_SIZE \
119  (USB_DESC_INTERFACE_SIZE + 5 + 5 + 4 + 5 + USB_DESC_ENDPOINT_SIZE + \
120  USB_DESC_INTERFACE_SIZE + (USB_DESC_ENDPOINT_SIZE * 2))
121 
122 #define IAD_CDC_IF_DESC_SET_SIZE \
123  (USB_DESC_INTERFACE_ASSOCIATION_SIZE + CDC_IF_DESC_SET_SIZE)
124 
125 #define CONFIG_DESC_DATA_SIZE (USB_DESC_CONFIGURATION_SIZE + (IAD_CDC_IF_DESC_SET_SIZE*USBD_NUMBER))
126 
127 /* Configuration Descriptor tree for a CDC.*/
128 static const uint8_t vcom_configuration_descriptor_data[CONFIG_DESC_DATA_SIZE] = {
129  /* Configuration Descriptor.*/
130  USB_DESC_CONFIGURATION(
131  CONFIG_DESC_DATA_SIZE, /* wTotalLength. */
132  USB_NUM_INTERFACES, /* bNumInterfaces. */
133  0x01, /* bConfigurationValue. */
134  0, /* iConfiguration. */
135  0x80, /* bmAttributes (self powered). */
136  50), /* bMaxPower (100mA). */
137 
138 
139  /* Interface Descriptor. USB serial 1.*/
140  USB_DESC_INTERFACE(
141  USB_CDC_CIF_NUM0, /* bInterfaceNumber. */
142  0x00, /* bAlternateSetting. */
143  0x01, /* bNumEndpoints. */
144  CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass */
145  CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */
146  0x00, /* bInterfaceProtocol (CDC section 4.4)*/
147  4), /* iInterface: Descriptor index */
148  /* Header Functional Descriptor (CDC section 5.2.3).*/
149  USB_DESC_BYTE (5), /* bLength. */
150  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
151  USB_DESC_BYTE (CDC_HEADER), /* bDescriptorSubtype */
152  USB_DESC_BCD (0x0110), /* bcdCDC. */
153  /* Call Management Functional Descriptor. */
154  USB_DESC_BYTE (5), /* bFunctionLength. */
155  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
156  USB_DESC_BYTE (CDC_CALL_MANAGEMENT), /* bDescriptorSubtype */
157  USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
158  USB_DESC_BYTE (USB_CDC_DIF_NUM0), /* bDataInterface. */
159  /* ACM Functional Descriptor.*/
160  USB_DESC_BYTE (4), /* bFunctionLength. */
161  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
162  USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT), /* bDescriptorSubtype */
163  USB_DESC_BYTE (0x02), /* bmCapabilities. */
164  /* Union Functional Descriptor.*/
165  USB_DESC_BYTE (5), /* bFunctionLength. */
166  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
167  USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype */
168  USB_DESC_BYTE (USB_CDC_CIF_NUM0), /* bMasterInterface */
169  USB_DESC_BYTE (USB_CDC_DIF_NUM0), /* bSlaveInterface0 */
170  /* Endpoint, Interrupt IN.*/
171  USB_DESC_ENDPOINT(
172  USB_ENDPOINT_IN(USBD1_INTERRUPT_REQUEST_EP),
173  USB_EP_MODE_TYPE_INTR, /* bmAttributes (Interrupt). */
174  USB_INTERRUPT_REQUEST_SIZE, /* wMaxPacketSize. */
175  0xFF), /* bInterval. */
176  /* Interface Descriptor.*/
177  USB_DESC_INTERFACE(
178  USB_CDC_DIF_NUM0, /* bInterfaceNumber. */
179  0x00, /* bAlternateSetting. */
180  0x02, /* bNumEndpoints. */
181  CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */
182  0x00, /* bInterfaceSubClass (CDC sec. 4.6)*/
183  0x00, /* bInterfaceProtocol (CDC sec. 4.7)*/
184  0x00), /* iInterface. */
185  /* Endpoint, Bulk OUT.*/
186  USB_DESC_ENDPOINT(
187  USB_ENDPOINT_OUT(USBD1_DATA_AVAILABLE_EP), /* bEndpointAddress. */
188  USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */
189  USB_DATA_SIZE, /* wMaxPacketSize. */
190  0x00), /* bInterval. */
191  /* Endpoint, Bulk IN*/
192  USB_DESC_ENDPOINT(
193  USB_ENDPOINT_IN(USBD1_DATA_REQUEST_EP), /* bEndpointAddress. */
194  USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */
195  USB_DATA_SIZE, /* wMaxPacketSize. */
196  0x00), /* bInterval. */
197 
198 
199 
200 #if USBD_NUMBER >= 2
201  /* Interface Descriptor. USB serial 2.*/
202  USB_DESC_INTERFACE(
203  USB_CDC_CIF_NUM1, /* bInterfaceNumber. */
204  0x00, /* bAlternateSetting. */
205  0x01, /* bNumEndpoints. */
206  CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass */
207  CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */
208  0x00, /* bInterfaceProtocol (CDC section 4.4)*/
209  5), /* iInterface: Descriptor index */
210  /* Header Functional Descriptor (CDC section 5.2.3).*/
211  USB_DESC_BYTE (5), /* bLength. */
212  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
213  USB_DESC_BYTE (CDC_HEADER), /* bDescriptorSubtype */
214  USB_DESC_BCD (0x0110), /* bcdCDC. */
215  /* Call Management Functional Descriptor. */
216  USB_DESC_BYTE (5), /* bFunctionLength. */
217  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
218  USB_DESC_BYTE (CDC_CALL_MANAGEMENT), /* bDescriptorSubtype */
219  USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */
220  USB_DESC_BYTE (USB_CDC_DIF_NUM1), /* bDataInterface. */
221  /* ACM Functional Descriptor.*/
222  USB_DESC_BYTE (4), /* bFunctionLength. */
223  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
224  USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT), /* bDescriptorSubtype */
225  USB_DESC_BYTE (0x02), /* bmCapabilities. */
226  /* Union Functional Descriptor.*/
227  USB_DESC_BYTE (5), /* bFunctionLength. */
228  USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */
229  USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype */
230  USB_DESC_BYTE (USB_CDC_CIF_NUM1), /* bMasterInterface */
231  USB_DESC_BYTE (USB_CDC_DIF_NUM1), /* bSlaveInterface0 */
232  /* Endpoint, Interrupt IN.*/
233  USB_DESC_ENDPOINT(
234  USB_ENDPOINT_IN(USBD2_INTERRUPT_REQUEST_EP),
235  USB_EP_MODE_TYPE_INTR, /* bmAttributes (Interrupt). */
236  USB_INTERRUPT_REQUEST_SIZE, /* wMaxPacketSize. */
237  0xFF), /* bInterval. */
238  /* Interface Descriptor.*/
239  USB_DESC_INTERFACE(
240  USB_CDC_DIF_NUM1, /* bInterfaceNumber. */
241  0x00, /* bAlternateSetting. */
242  0x02, /* bNumEndpoints. */
243  CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */
244  0x00, /* bInterfaceSubClass (CDC sec. 4.6)*/
245  0x00, /* bInterfaceProtocol (CDC sec. 4.7)*/
246  0x00), /* iInterface. */
247  /* Endpoint, Bulk OUT.*/
248  USB_DESC_ENDPOINT(
249  USB_ENDPOINT_OUT(USBD2_DATA_AVAILABLE_EP), /* bEndpointAddress. */
250  USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */
251  USB_DATA_SIZE, /* wMaxPacketSize. */
252  0x00), /* bInterval. */
253  /* Endpoint, Bulk IN*/
254  USB_DESC_ENDPOINT(
255  USB_ENDPOINT_IN(USBD2_DATA_REQUEST_EP), /* bEndpointAddress. */
256  USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */
257  USB_DATA_SIZE, /* wMaxPacketSize. */
258  0x00) /* bInterval. */
259 #endif
260 };
261 
262 /*
263  * Configuration Descriptor wrapper.
264  */
265 static const USBDescriptor vcom_configuration_descriptor = {
266  sizeof vcom_configuration_descriptor_data,
267  vcom_configuration_descriptor_data
268 };
269 
270 /*
271  * U.S. English language identifier.
272  */
273 static const uint8_t vcom_string0[] = {
274  USB_DESC_BYTE(4), /* bLength. */
275  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
276  USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */
277 };
278 
279 /*
280  * Vendor string.
281  */
282 static const uint8_t vcom_string1[] = {
283  USB_DESC_BYTE(28), /* bLength. */
284  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
285  'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0,
286  'i', 0, ' ', 0, 'U', 0, 'A', 0, 'V', 0
287 };
288 
289 /*
290  * Device Description string.
291  */
292 static const uint8_t vcom_string2[] = {
293  USB_DESC_BYTE(34), /* bLength. */
294  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
295  'C', 0, 'D', 0, 'C', 0, ' ', 0, 'S', 0, 'e', 0, 'r', 0, 'i', 0,
296  'a', 0, 'l', 0, ' ', 0, 'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0
297 };
298 
299 /*
300  * Serial Number string.
301  */
302 static const uint8_t vcom_string3[] = {
303  USB_DESC_BYTE(8), /* bLength. */
304  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
305  '0' + CH_KERNEL_MAJOR, 0,
306  '0' + CH_KERNEL_MINOR, 0,
307  '0' + CH_KERNEL_PATCH, 0
308 };
309 
313 static const uint8_t vcom_string4[] = {
314  USB_DESC_BYTE(58), /* bLength. */
315  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
316  'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0,
317  'i', 0, ' ', 0, 'U', 0, 'A', 0, 'V', 0, ' ', 0, 't', 0, 'e', 0,
318  'l', 0, 'e', 0, 'm', 0, 'e', 0, 't', 0, 'r', 0, 'y', 0, ' ', 0,
319  'P', 0, 'o', 0, 'r', 0, 't', 0
320 };
321 
322 #if USBD_NUMBER >= 2
326 static const uint8_t vcom_string5[] = {
327  USB_DESC_BYTE(54), /* bLength. */
328  USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
329  'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0,
330  'i', 0, ' ', 0, 'U', 0, 'A', 0, 'V', 0, ' ', 0, 'd', 0, 'e', 0,
331  'b', 0, 'u', 0, 'g', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0
332 };
333 #endif
334 
335 /*
336  * Strings wrappers array.
337  */
338 static const USBDescriptor vcom_strings[] = {
339  {sizeof vcom_string0, vcom_string0},
340  {sizeof vcom_string1, vcom_string1},
341  {sizeof vcom_string2, vcom_string2},
342  {sizeof vcom_string3, vcom_string3},
343  {sizeof vcom_string4, vcom_string4},
344 #if USBD_NUMBER >= 2
345  {sizeof vcom_string5, vcom_string5}
346 #endif
347 };
348 
349 
350 static SerialUSBDriver SDU1;
351 #if USBD_NUMBER >= 2
352 static SerialUSBDriver SDU2;
353 #endif
354 
355 /*
356  * Handles the GET_DESCRIPTOR callback. All required descriptors must be
357  * handled here.
358  */
359 static const USBDescriptor *get_descriptor(USBDriver *usbp,
360  uint8_t dtype,
361  uint8_t dindex,
362  uint16_t lang) {
363 
364  (void)usbp;
365  (void)lang;
366  switch (dtype) {
367  case USB_DESCRIPTOR_DEVICE:
368  return &vcom_device_descriptor;
369  case USB_DESCRIPTOR_CONFIGURATION:
370  return &vcom_configuration_descriptor;
371  case USB_DESCRIPTOR_STRING:
372  if (dindex < 6)
373  return &vcom_strings[dindex];
374  }
375  return NULL;
376 }
377 
378 
382 static USBInEndpointState ep1instate;
383 
387 static USBOutEndpointState ep1outstate;
388 
392 static const USBEndpointConfig ep1config = {
393  USB_EP_MODE_TYPE_BULK,
394  NULL,
395  sduDataTransmitted,
396  sduDataReceived,
397  USB_DATA_SIZE,
398  USB_DATA_SIZE,
399  &ep1instate,
400  &ep1outstate,
401  2,
402  NULL
403 };
404 
408 static USBInEndpointState ep2instate;
409 
413 static const USBEndpointConfig ep2config = {
414  USB_EP_MODE_TYPE_INTR,
415  NULL,
416  sduInterruptTransmitted,
417  NULL,
418  USB_INTERRUPT_REQUEST_SIZE,
419  0x0000,
420  &ep2instate,
421  NULL,
422  1,
423  NULL
424 };
425 
426 #if USBD_NUMBER >= 2
430 static USBInEndpointState ep3instate;
431 
435 static USBOutEndpointState ep3outstate;
436 
440 static const USBEndpointConfig ep3config = {
441  USB_EP_MODE_TYPE_BULK,
442  NULL,
443  sduDataTransmitted,
444  sduDataReceived,
445  USB_DATA_SIZE,
446  USB_DATA_SIZE,
447  &ep3instate,
448  &ep3outstate,
449  2,
450  NULL
451 };
452 
456 static USBInEndpointState ep4instate;
457 
461 static const USBEndpointConfig ep4config = {
462  USB_EP_MODE_TYPE_INTR,
463  NULL,
464  sduInterruptTransmitted,
465  NULL,
466  USB_INTERRUPT_REQUEST_SIZE,
467  0x0000,
468  &ep4instate,
469  NULL,
470  1,
471  NULL
472 };
473 #endif
474 
475 
476 
477 /*
478  * Handles the USB driver global events.
479  */
480 static void usb_event(USBDriver *usbp, usbevent_t event) {
481 
482  switch (event) {
483  case USB_EVENT_RESET:
484  return;
485  case USB_EVENT_ADDRESS:
486  return;
487  case USB_EVENT_CONFIGURED:
488  chSysLockFromISR();
489 
490 
491  if (usbp->state == USB_ACTIVE) {
492  /* Enables the endpoints specified into the configuration.
493  Note, this callback is invoked from an ISR so I-Class functions
494  must be used.*/
495  usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
496  usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
497 #if USBD_NUMBER >= 2
498  usbInitEndpointI(usbp, USBD2_DATA_REQUEST_EP, &ep3config);
499  usbInitEndpointI(usbp, USBD2_INTERRUPT_REQUEST_EP, &ep4config);
500 #endif
501  /* Resetting the state of the CDC subsystem.*/
502  sduConfigureHookI(&SDU1);
503 #if USBD_NUMBER >= 2
504  sduConfigureHookI(&SDU2);
505 #endif
506  }
507  else if (usbp->state == USB_SELECTED) {
508  usbDisableEndpointsI(usbp);
509  }
510 
511  chSysUnlockFromISR();
512  return;
513  case USB_EVENT_UNCONFIGURED:
514  return;
515  case USB_EVENT_SUSPEND:
516  chSysLockFromISR();
517 
518  /* Disconnection event on suspend.*/
519  sduSuspendHookI(&SDU1);
520 #if USBD_NUMBER >= 2
521  sduSuspendHookI(&SDU2);
522 #endif
523  chSysUnlockFromISR();
524  return;
525  case USB_EVENT_WAKEUP:
526  return;
527  case USB_EVENT_STALLED:
528  return;
529  }
530  return;
531 }
532 
533 /*
534  * Handles the USB driver global events.
535  */
536 static void sof_handler(USBDriver *usbp)
537 {
538  (void)usbp;
539 
540  chSysLockFromISR();
541  sduSOFHookI(&SDU1);
542 #if USBD_NUMBER >= 2
543  sduSOFHookI(&SDU2);
544 #endif
545  chSysUnlockFromISR();
546 }
547 
548 /*
549  * Serial over USB driver configuration.
550  */
551 static const USBConfig usbcfg = {
552  usb_event,
553  get_descriptor,
554  sduRequestsHook,
555  sof_handler
556 };
557 
558 static SerialUSBConfig serusbcfg1;
559 #if USBD_NUMBER >= 2
560 static SerialUSBConfig serusbcfg2;
561 #endif
562 
563 USBDriver *usbGetDriver (void)
564 {
565  return serusbcfg1.usbp;
566 }
567 
568 
569 
570 bool isUsbConnected(void)
571 {
572  static bool hasEverReceive = FALSE;
573 
574 #if (CH_KERNEL_MAJOR <= 3)
575  if (inputAvailEL.el_listener == NULL)
576 #else
577  if (inputAvailEL.listener == NULL)
578 #endif
579  return FALSE;
580 
581  if (hasEverReceive)
582  return TRUE;
583  else
584  return ((hasEverReceive = chEvtGetAndClearFlags(&inputAvailEL)) != 0);
585 }
586 
587 
588 
589 
590 void usbSerialReset(SerialUSBDriver *sdu)
591 {
592  usbStop(serusbcfg1.usbp);
593  usbDisconnectBus(serusbcfg1.usbp);
594  sduStop (sdu);
595 
596  chThdSleepMilliseconds(10);
597  sduStart(sdu, &serusbcfg1);
598  usbDisconnectBus(serusbcfg1.usbp);
599  chThdSleepMilliseconds(900);
600  usbStart(serusbcfg1.usbp, &usbcfg);
601  usbConnectBus(serusbcfg1.usbp);
602 }
603 
604 
605 /*
606  * For USB telemetry & generic device API
607  */
608 // Periph with generic device API
610 #if USBD_NUMBER >= 2
611 struct usb_serial_periph usb_serial_debug;
612 #endif
613 
614 // Functions for the generic device API
615 static int usb_serial_check_free_space(struct usb_serial_periph *p __attribute__((unused)),
616  long *fd __attribute__((unused)),
617  uint16_t len)
618 {
619  return len;
620 }
621 
622 static void usb_serial_transmit(struct usb_serial_periph *p __attribute__((unused)),
623  long fd __attribute__((unused)),
624  uint8_t byte)
625 {
626  obqPutTimeout(&((SerialUSBDriver *)p->reg_addr)->obqueue, byte, TIME_IMMEDIATE);
627 }
628 
629 static void usb_serial_transmit_buffer(struct usb_serial_periph *p __attribute__((unused)),
630  long fd __attribute__((unused)),
631  uint8_t *data, uint16_t len)
632 {
633  obqWriteTimeout(&((SerialUSBDriver *)p->reg_addr)->obqueue, data, len, TIME_IMMEDIATE);
634 }
635 
636 static void usb_serial_send(struct usb_serial_periph *p __attribute__((unused)), long fd __attribute__((unused)))
637 {
638  // TODO
639 }
640 
641 static int usb_serial_char_available(struct usb_serial_periph *p __attribute__((unused)))
642 {
643  // some bytes in the buffer
644  if(p->nb_bytes > 0) {
645  return p->nb_bytes;
646  }
647 
648  uint16_t write_idx = (p->rx_read_idx + p->nb_bytes) % USB_RX_BUFFER_SIZE;
649 
650  // no bytes in the buffer, try to get one
651  msg_t res = ibqGetTimeout(&(((SerialUSBDriver*)(p->reg_addr))->ibqueue), TIME_IMMEDIATE);
652  if(res >= 0) {
653  // got a byte. put it in the buffer.
654  p->rx_buf[write_idx] = (uint8_t) res;
655  p->nb_bytes++;
656  return p->nb_bytes;
657  } else {
658  // timeout or queue suspended. No data available.
659  return 0;
660  }
661 }
662 
663 static uint8_t usb_serial_getch(struct usb_serial_periph *p __attribute__((unused)))
664 {
665  if(p->nb_bytes > 0) {
666  uint8_t ret = p->rx_buf[p->rx_read_idx];
667  p->rx_read_idx = (p->rx_read_idx + 1) % USB_RX_BUFFER_SIZE;
668  p->nb_bytes--;
669  return ret;
670  } else {
671  return ibqGetTimeout(&((SerialUSBDriver *)p->reg_addr)->ibqueue, TIME_IMMEDIATE);
672  }
673 }
674 
675 
676 
677 
678 /*
679  * usb init
680  */
681 void VCOM_init()
682 {
683  serusbcfg1.usbp = &SERIAL_USB;
684  serusbcfg1.bulk_in = USBD1_DATA_REQUEST_EP;
685  serusbcfg1.bulk_out = USBD1_DATA_AVAILABLE_EP;
686  serusbcfg1.int_in = USBD1_INTERRUPT_REQUEST_EP;
687 #if USBD_NUMBER >= 2
688  serusbcfg2.usbp = &SERIAL_USB;
689  serusbcfg2.bulk_in = USBD2_DATA_REQUEST_EP;
690  serusbcfg2.bulk_out = USBD2_DATA_AVAILABLE_EP;
691  serusbcfg2.int_in = USBD2_INTERRUPT_REQUEST_EP;
692 #endif
693 
694  sduObjectInit(&SDU1);
695  sduStart(&SDU1, &serusbcfg1);
696 #if USBD_NUMBER >= 2
697  sduObjectInit(&SDU2);
698  sduStart(&SDU2, &serusbcfg2);
699 #endif
700 
701  usbDisconnectBus(serusbcfg1.usbp);
702  chThdSleepMilliseconds(1000);
703  usbStart(serusbcfg1.usbp, &usbcfg);
704  usbConnectBus(serusbcfg1.usbp);
705 
706  chEvtRegisterMask(chnGetEventSource(&SDU1), &inputAvailEL, CHN_INPUT_AVAILABLE);
707 
708 
709 
710  usb_serial.nb_bytes = 0;
712  usb_serial.reg_addr = &SDU1;
713  // Configure generic device
714  usb_serial.device.periph = (void *)(&usb_serial);
715  usb_serial.device.check_free_space = (check_free_space_t) usb_serial_check_free_space;
716  usb_serial.device.put_byte = (put_byte_t) usb_serial_transmit;
717  usb_serial.device.put_buffer = (put_buffer_t) usb_serial_transmit_buffer;
718  usb_serial.device.send_message = (send_message_t) usb_serial_send;
719  usb_serial.device.char_available = (char_available_t) usb_serial_char_available;
720  usb_serial.device.get_byte = (get_byte_t) usb_serial_getch;
721 
722 
723 #if USBD_NUMBER >= 2
724  usb_serial_debug.nb_bytes = 0;
725  usb_serial_debug.rx_read_idx = 0;
726  usb_serial_debug.reg_addr = &SDU2;
727  // Configure generic device
728  usb_serial_debug.device.periph = (void *)(&usb_serial_debug);
729  usb_serial_debug.device.check_free_space = (check_free_space_t) usb_serial_check_free_space;
730  usb_serial_debug.device.put_byte = (put_byte_t) usb_serial_transmit;
731  usb_serial_debug.device.put_buffer = (put_buffer_t) usb_serial_transmit_buffer;
732  usb_serial_debug.device.send_message = (send_message_t) usb_serial_send;
733  usb_serial_debug.device.char_available = (char_available_t) usb_serial_char_available;
734  usb_serial_debug.device.get_byte = (get_byte_t) usb_serial_getch;
735 #endif
736 }
737 
738 
739 int VCOM_putchar(int c) {
740  if(!isUsbConnected()) {
741  return -1;
742  }
743  streamPut((SerialUSBDriver*)(usb_serial.reg_addr), c);
744  return c;
745 
746 }
747 
748 int VCOM_getchar(void) {
749  return usb_serial_getch(&usb_serial);
750 }
751 
752 int VCOM_peekchar(int ofs __attribute__((unused))) {
753  // Dummy implementation
754  return 0;
755 }
756 
757 bool VCOM_check_free_space(uint16_t len __attribute__((unused))) {
758  return true;
759 }
760 
761 int VCOM_check_available(void) {
763 }
764 
765 void VCOM_set_linecoding(uint8_t mode __attribute__((unused))) {}
766 
767 void VCOM_allow_linecoding(uint8_t mode __attribute__((unused))) {}
768 
769 void VCOM_send_message(void) {}
770 
771 void VCOM_event(void) {}
772 
773 
774 #endif // HAL_USE_SERIAL_USB
static float p[2][2]
int fd
Definition: serial.c:26
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:65
#define TRUE
Definition: std.h:4
#define FALSE
Definition: std.h:5
void VCOM_event(void)
Poll usb (required by libopencm3).
Definition: usb_ser_hw.c:468
int VCOM_getchar(void)
Reads one character from VCOM port.
Definition: usb_ser_hw.c:425
int VCOM_putchar(int c)
Writes one character to VCOM port fifo.
Definition: usb_ser_hw.c:397
static int usb_serial_check_free_space(struct usb_serial_periph *p, long *fd, uint16_t len)
Definition: usb_ser_hw.c:526
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 void usb_serial_transmit(struct usb_serial_periph *p, long fd, uint8_t byte)
Definition: usb_ser_hw.c:533
int VCOM_check_available(void)
Checks if data available in VCOM buffer.
Definition: usb_ser_hw.c:459
int VCOM_peekchar(int ofs)
Reads one character from VCOM port without removing it from the queue.
Definition: usb_ser_hw.c:438
void VCOM_init(void)
Definition: usb_ser_hw.c:565
void VCOM_send_message(void)
Send data from fifo right now.
Definition: usb_ser_hw.c:487
struct usb_serial_periph usb_serial
Definition: usb_ser_hw.c:523
static uint8_t usb_serial_getch(struct usb_serial_periph *p)
Definition: usb_ser_hw.c:560
static void usb_serial_send(struct usb_serial_periph *p, long fd)
Definition: usb_ser_hw.c:550
static int usb_serial_char_available(struct usb_serial_periph *p)
Definition: usb_ser_hw.c:555
bool VCOM_check_free_space(uint16_t len)
Checks if buffer free in VCOM buffer.
Definition: usb_ser_hw.c:450
arch independent USB API
uint16_t rx_read_idx
Definition: usb_serial.h:54
void VCOM_set_linecoding(uint8_t mode)
struct link_device device
Generic device interface.
Definition: usb_serial.h:59
void VCOM_allow_linecoding(uint8_t mode)
#define USB_RX_BUFFER_SIZE
Definition: usb_serial.h:38
uint16_t nb_bytes
Definition: usb_serial.h:55
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98