27 #include "hal_serial_usb.h"
30 #if HAL_USE_SERIAL_USB
33 #define SERIAL_USB USBD1
39 #ifndef USBD1_DATA_REQUEST_EP
40 #define USBD1_DATA_REQUEST_EP 1
42 #ifndef USBD1_DATA_AVAILABLE_EP
43 #define USBD1_DATA_AVAILABLE_EP 1
45 #ifndef USBD1_INTERRUPT_REQUEST_EP
46 #define USBD1_INTERRUPT_REQUEST_EP 2
52 #define USB_NUM_INTERFACES 2
53 #define USB_CDC_CIF_NUM0 0
54 #define USB_CDC_DIF_NUM0 1
59 #ifndef USBD2_DATA_REQUEST_EP
60 #define USBD2_DATA_REQUEST_EP 3
62 #ifndef USBD2_DATA_AVAILABLE_EP
63 #define USBD2_DATA_AVAILABLE_EP 3
65 #ifndef USBD2_INTERRUPT_REQUEST_EP
66 #define USBD2_INTERRUPT_REQUEST_EP 4
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
75 #define USB_INTERRUPT_REQUEST_SIZE 0x10
76 #define USB_DATA_SIZE 0x40
80 #if (CH_KERNEL_MAJOR == 2)
81 static EventListener inputAvailEL = {NULL, NULL, 0, 0};
83 static event_listener_t inputAvailEL = {NULL, NULL, 0, 0, 0};
94 static const uint8_t vcom_device_descriptor_data[18] = {
95 USB_DESC_DEVICE (0x0200,
113 static const USBDescriptor vcom_device_descriptor = {
114 sizeof vcom_device_descriptor_data,
115 vcom_device_descriptor_data
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))
122 #define IAD_CDC_IF_DESC_SET_SIZE \
123 (USB_DESC_INTERFACE_ASSOCIATION_SIZE + CDC_IF_DESC_SET_SIZE)
125 #define CONFIG_DESC_DATA_SIZE (USB_DESC_CONFIGURATION_SIZE + (IAD_CDC_IF_DESC_SET_SIZE*USBD_NUMBER))
128 static const uint8_t vcom_configuration_descriptor_data[CONFIG_DESC_DATA_SIZE] = {
130 USB_DESC_CONFIGURATION(
131 CONFIG_DESC_DATA_SIZE,
144 CDC_COMMUNICATION_INTERFACE_CLASS,
145 CDC_ABSTRACT_CONTROL_MODEL,
150 USB_DESC_BYTE (CDC_CS_INTERFACE),
151 USB_DESC_BYTE (CDC_HEADER),
152 USB_DESC_BCD (0x0110),
155 USB_DESC_BYTE (CDC_CS_INTERFACE),
156 USB_DESC_BYTE (CDC_CALL_MANAGEMENT),
157 USB_DESC_BYTE (0x00),
158 USB_DESC_BYTE (USB_CDC_DIF_NUM0),
161 USB_DESC_BYTE (CDC_CS_INTERFACE),
162 USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT),
163 USB_DESC_BYTE (0x02),
166 USB_DESC_BYTE (CDC_CS_INTERFACE),
167 USB_DESC_BYTE (CDC_UNION),
168 USB_DESC_BYTE (USB_CDC_CIF_NUM0),
169 USB_DESC_BYTE (USB_CDC_DIF_NUM0),
172 USB_ENDPOINT_IN(USBD1_INTERRUPT_REQUEST_EP),
173 USB_EP_MODE_TYPE_INTR,
174 USB_INTERRUPT_REQUEST_SIZE,
181 CDC_DATA_INTERFACE_CLASS,
187 USB_ENDPOINT_OUT(USBD1_DATA_AVAILABLE_EP),
188 USB_EP_MODE_TYPE_BULK,
193 USB_ENDPOINT_IN(USBD1_DATA_REQUEST_EP),
194 USB_EP_MODE_TYPE_BULK,
206 CDC_COMMUNICATION_INTERFACE_CLASS,
207 CDC_ABSTRACT_CONTROL_MODEL,
212 USB_DESC_BYTE (CDC_CS_INTERFACE),
213 USB_DESC_BYTE (CDC_HEADER),
214 USB_DESC_BCD (0x0110),
217 USB_DESC_BYTE (CDC_CS_INTERFACE),
218 USB_DESC_BYTE (CDC_CALL_MANAGEMENT),
219 USB_DESC_BYTE (0x00),
220 USB_DESC_BYTE (USB_CDC_DIF_NUM1),
223 USB_DESC_BYTE (CDC_CS_INTERFACE),
224 USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT),
225 USB_DESC_BYTE (0x02),
228 USB_DESC_BYTE (CDC_CS_INTERFACE),
229 USB_DESC_BYTE (CDC_UNION),
230 USB_DESC_BYTE (USB_CDC_CIF_NUM1),
231 USB_DESC_BYTE (USB_CDC_DIF_NUM1),
234 USB_ENDPOINT_IN(USBD2_INTERRUPT_REQUEST_EP),
235 USB_EP_MODE_TYPE_INTR,
236 USB_INTERRUPT_REQUEST_SIZE,
243 CDC_DATA_INTERFACE_CLASS,
249 USB_ENDPOINT_OUT(USBD2_DATA_AVAILABLE_EP),
250 USB_EP_MODE_TYPE_BULK,
255 USB_ENDPOINT_IN(USBD2_DATA_REQUEST_EP),
256 USB_EP_MODE_TYPE_BULK,
265 static const USBDescriptor vcom_configuration_descriptor = {
266 sizeof vcom_configuration_descriptor_data,
267 vcom_configuration_descriptor_data
273 static const uint8_t vcom_string0[] = {
275 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
276 USB_DESC_WORD(0x0409)
282 static const uint8_t vcom_string1[] = {
284 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
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
292 static const uint8_t vcom_string2[] = {
294 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
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
302 static const uint8_t vcom_string3[] = {
304 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
305 '0' + CH_KERNEL_MAJOR, 0,
306 '0' + CH_KERNEL_MINOR, 0,
307 '0' + CH_KERNEL_PATCH, 0
313 static const uint8_t vcom_string4[] = {
315 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
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
326 static const uint8_t vcom_string5[] = {
328 USB_DESC_BYTE(USB_DESCRIPTOR_STRING),
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
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},
345 {
sizeof vcom_string5, vcom_string5}
350 static SerialUSBDriver SDU1;
352 static SerialUSBDriver SDU2;
359 static const USBDescriptor *get_descriptor(USBDriver *usbp,
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:
373 return &vcom_strings[dindex];
382 static USBInEndpointState ep1instate;
387 static USBOutEndpointState ep1outstate;
392 static const USBEndpointConfig ep1config = {
393 USB_EP_MODE_TYPE_BULK,
408 static USBInEndpointState ep2instate;
413 static const USBEndpointConfig ep2config = {
414 USB_EP_MODE_TYPE_INTR,
416 sduInterruptTransmitted,
418 USB_INTERRUPT_REQUEST_SIZE,
430 static USBInEndpointState ep3instate;
435 static USBOutEndpointState ep3outstate;
440 static const USBEndpointConfig ep3config = {
441 USB_EP_MODE_TYPE_BULK,
456 static USBInEndpointState ep4instate;
461 static const USBEndpointConfig ep4config = {
462 USB_EP_MODE_TYPE_INTR,
464 sduInterruptTransmitted,
466 USB_INTERRUPT_REQUEST_SIZE,
480 static void usb_event(USBDriver *usbp, usbevent_t event) {
483 case USB_EVENT_RESET:
485 case USB_EVENT_ADDRESS:
487 case USB_EVENT_CONFIGURED:
491 if (usbp->state == USB_ACTIVE) {
495 usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
496 usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
498 usbInitEndpointI(usbp, USBD2_DATA_REQUEST_EP, &ep3config);
499 usbInitEndpointI(usbp, USBD2_INTERRUPT_REQUEST_EP, &ep4config);
502 sduConfigureHookI(&SDU1);
504 sduConfigureHookI(&SDU2);
507 else if (usbp->state == USB_SELECTED) {
508 usbDisableEndpointsI(usbp);
511 chSysUnlockFromISR();
513 case USB_EVENT_UNCONFIGURED:
515 case USB_EVENT_SUSPEND:
519 sduSuspendHookI(&SDU1);
521 sduSuspendHookI(&SDU2);
523 chSysUnlockFromISR();
525 case USB_EVENT_WAKEUP:
527 case USB_EVENT_STALLED:
536 static void sof_handler(USBDriver *usbp)
545 chSysUnlockFromISR();
551 static const USBConfig usbcfg = {
558 static SerialUSBConfig serusbcfg1;
560 static SerialUSBConfig serusbcfg2;
563 USBDriver *usbGetDriver (
void)
565 return serusbcfg1.usbp;
570 bool isUsbConnected(
void)
572 static bool hasEverReceive =
FALSE;
574 #if (CH_KERNEL_MAJOR <= 3)
575 if (inputAvailEL.el_listener == NULL)
577 if (inputAvailEL.listener == NULL)
584 return ((hasEverReceive = chEvtGetAndClearFlags(&inputAvailEL)) != 0);
590 void usbSerialReset(SerialUSBDriver *sdu)
592 usbStop(serusbcfg1.usbp);
593 usbDisconnectBus(serusbcfg1.usbp);
596 chThdSleepMilliseconds(10);
597 sduStart(sdu, &serusbcfg1);
598 usbDisconnectBus(serusbcfg1.usbp);
599 chThdSleepMilliseconds(900);
600 usbStart(serusbcfg1.usbp, &usbcfg);
601 usbConnectBus(serusbcfg1.usbp);
616 long *
fd __attribute__((unused)),
623 long fd __attribute__((unused)),
626 obqPutTimeout(&((SerialUSBDriver *)
p->reg_addr)->obqueue,
byte, TIME_IMMEDIATE);
630 long fd __attribute__((unused)),
633 obqWriteTimeout(&((SerialUSBDriver *)
p->reg_addr)->obqueue, data, len, TIME_IMMEDIATE);
644 if(
p->nb_bytes > 0) {
651 msg_t res = ibqGetTimeout(&(((SerialUSBDriver*)(
p->reg_addr))->ibqueue), TIME_IMMEDIATE);
654 p->rx_buf[write_idx] = (
uint8_t) res;
665 if(
p->nb_bytes > 0) {
671 return ibqGetTimeout(&((SerialUSBDriver *)
p->reg_addr)->ibqueue, TIME_IMMEDIATE);
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;
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;
694 sduObjectInit(&SDU1);
695 sduStart(&SDU1, &serusbcfg1);
697 sduObjectInit(&SDU2);
698 sduStart(&SDU2, &serusbcfg2);
701 usbDisconnectBus(serusbcfg1.usbp);
702 chThdSleepMilliseconds(1000);
703 usbStart(serusbcfg1.usbp, &usbcfg);
704 usbConnectBus(serusbcfg1.usbp);
706 chEvtRegisterMask(chnGetEventSource(&SDU1), &inputAvailEL, CHN_INPUT_AVAILABLE);
724 usb_serial_debug.nb_bytes = 0;
725 usb_serial_debug.rx_read_idx = 0;
726 usb_serial_debug.reg_addr = &SDU2;
728 usb_serial_debug.device.periph = (
void *)(&usb_serial_debug);
732 usb_serial_debug.device.send_message = (send_message_t)
usb_serial_send;
740 if(!isUsbConnected()) {
static uint8_t mode
mode holds the current sonar mode mode = 0 used at high altitude, uses 16 wave patterns mode = 1 used...
void VCOM_event(void)
Poll usb (required by libopencm3).
int VCOM_getchar(void)
Reads one character from VCOM port.
int VCOM_putchar(int c)
Writes one character to VCOM port fifo.
static int usb_serial_check_free_space(struct usb_serial_periph *p, long *fd, uint16_t len)
static void usb_serial_transmit_buffer(struct usb_serial_periph *p, long fd, uint8_t *data, uint16_t len)
static void usb_serial_transmit(struct usb_serial_periph *p, long fd, uint8_t byte)
int VCOM_check_available(void)
Checks if data available in VCOM buffer.
int VCOM_peekchar(int ofs)
Reads one character from VCOM port without removing it from the queue.
void VCOM_send_message(void)
Send data from fifo right now.
struct usb_serial_periph usb_serial
static uint8_t usb_serial_getch(struct usb_serial_periph *p)
static void usb_serial_send(struct usb_serial_periph *p, long fd)
static int usb_serial_char_available(struct usb_serial_periph *p)
bool VCOM_check_free_space(uint16_t len)
Checks if buffer free in VCOM buffer.
void VCOM_set_linecoding(uint8_t mode)
struct link_device device
Generic device interface.
void VCOM_allow_linecoding(uint8_t mode)
#define USB_RX_BUFFER_SIZE
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.