Add support for a dual serial port configuration (USB_DUAL_SERIAL), providing a composite USB device, comprised of two serial ports. The second serial port is called usb_serial2 (C) or SerialA (C++). Note that no dummy C++ class is created if USB_DISABLED is defined, unlike for the first port. This increases binary size by ca. 1.2 KiB (720 bytes for USB buffers). Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>teensy4-core
@@ -52,6 +52,7 @@ | |||
#include "avr_emulation.h" | |||
#include "usb_serial.h" | |||
#include "usb_serial2.h" | |||
#include "usb_seremu.h" | |||
#include "usb_keyboard.h" | |||
#include "usb_mouse.h" |
@@ -484,7 +484,14 @@ static uint8_t flightsim_report_desc[] = { | |||
#define CDC_DATA_INTERFACE_DESC_SIZE 0 | |||
#endif | |||
#define MIDI_INTERFACE_DESC_POS CDC_DATA_INTERFACE_DESC_POS+CDC_DATA_INTERFACE_DESC_SIZE | |||
#define CDC2_DATA_INTERFACE_DESC_POS CDC_DATA_INTERFACE_DESC_POS+CDC_DATA_INTERFACE_DESC_SIZE | |||
#ifdef CDC2_DATA_INTERFACE | |||
#define CDC2_DATA_INTERFACE_DESC_SIZE 8 + 9+5+5+4+5+7+9+7+7 | |||
#else | |||
#define CDC2_DATA_INTERFACE_DESC_SIZE 0 | |||
#endif | |||
#define MIDI_INTERFACE_DESC_POS CDC2_DATA_INTERFACE_DESC_POS+CDC2_DATA_INTERFACE_DESC_SIZE | |||
#ifdef MIDI_INTERFACE | |||
#if !defined(MIDI_NUM_CABLES) || MIDI_NUM_CABLES < 1 || MIDI_NUM_CABLES > 16 | |||
#error "MIDI_NUM_CABLES must be defined between 1 to 16" | |||
@@ -678,6 +685,11 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { | |||
EMIT_CDC_DESCRIPTORS(CDC), | |||
#endif // CDC_DATA_INTERFACE | |||
#ifdef CDC2_DATA_INTERFACE | |||
EMIT_CDC_IAD_DESCRIPTOR(CDC2), | |||
EMIT_CDC_DESCRIPTORS(CDC2), | |||
#endif // CDC2_DATA_INTERFACE | |||
#ifdef MIDI_INTERFACE | |||
// Standard MS Interface Descriptor, | |||
9, // bLength |
@@ -140,6 +140,41 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports | |||
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY | |||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
#elif defined(USB_DUAL_SERIAL) | |||
#define VENDOR_ID 0x16C0 | |||
#define PRODUCT_ID 0x0483 | |||
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} | |||
#define MANUFACTURER_NAME_LEN 11 | |||
#define PRODUCT_NAME {'D','u','a','l',' ','S','e','r','i','a','l'} | |||
#define PRODUCT_NAME_LEN 11 | |||
#define EP0_SIZE 64 | |||
#define NUM_ENDPOINTS 7 | |||
#define NUM_USB_BUFFERS 22 | |||
#define NUM_INTERFACE 4 | |||
#define CDC_IAD_DESCRIPTOR 1 // Serial | |||
#define CDC_STATUS_INTERFACE 0 | |||
#define CDC_DATA_INTERFACE 1 | |||
#define CDC_ACM_ENDPOINT 2 | |||
#define CDC_RX_ENDPOINT 3 | |||
#define CDC_TX_ENDPOINT 4 | |||
#define CDC_ACM_SIZE 16 | |||
#define CDC_RX_SIZE 64 | |||
#define CDC_TX_SIZE 64 | |||
#define CDC2_STATUS_INTERFACE 2 // SerialA | |||
#define CDC2_DATA_INTERFACE 3 | |||
#define CDC2_ACM_ENDPOINT 5 | |||
#define CDC2_RX_ENDPOINT 6 | |||
#define CDC2_TX_ENDPOINT 7 | |||
#define CDC2_ACM_SIZE 16 | |||
#define CDC2_RX_SIZE 64 | |||
#define CDC2_TX_SIZE 64 | |||
#define ENDPOINT2_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY | |||
#define ENDPOINT4_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
#define ENDPOINT5_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ONLY | |||
#define ENDPOINT7_CONFIG ENDPOINT_TRANSMIT_ONLY | |||
#elif defined(USB_KEYBOARDONLY) | |||
#define VENDOR_ID 0x16C0 | |||
#define PRODUCT_ID 0x04D0 |
@@ -360,6 +360,12 @@ static void usb_setup(void) | |||
usb_cdc_line_rtsdtr_millis = systick_millis_count; | |||
usb_cdc_line_rtsdtr = setup.wValue; | |||
break; | |||
#endif | |||
#ifdef CDC2_STATUS_INTERFACE | |||
case CDC2_STATUS_INTERFACE: | |||
usb_cdc2_line_rtsdtr_millis = systick_millis_count; | |||
usb_cdc2_line_rtsdtr = setup.wValue; | |||
break; | |||
#endif | |||
} | |||
//serial_print("set control line state\n"); | |||
@@ -608,6 +614,11 @@ static void usb_control(uint32_t stat) | |||
case CDC_STATUS_INTERFACE: | |||
dst = (uint8_t *)usb_cdc_line_coding; | |||
break; | |||
#endif | |||
#ifdef CDC2_STATUS_INTERFACE | |||
case CDC2_STATUS_INTERFACE: | |||
dst = (uint8_t *)usb_cdc2_line_coding; | |||
break; | |||
#endif | |||
} | |||
if (!dst) | |||
@@ -907,6 +918,13 @@ void usb_isr(void) | |||
if (t == 0) usb_serial_flush_callback(); | |||
} | |||
#endif | |||
#ifdef CDC2_DATA_INTERFACE | |||
t = usb_cdc2_transmit_flush_timer; | |||
if (t) { | |||
usb_cdc2_transmit_flush_timer = --t; | |||
if (t == 0) usb_serial2_flush_callback(); | |||
} | |||
#endif | |||
#ifdef SEREMU_INTERFACE | |||
t = usb_seremu_transmit_flush_timer; | |||
if (t) { |
@@ -114,6 +114,10 @@ extern void usb_touchscreen_update_callback(void); | |||
#include "usb_serial.h" | |||
#endif | |||
#ifdef CDC2_DATA_INTERFACE | |||
#include "usb_serial2.h" | |||
#endif | |||
#else // F_CPU < 20000000 | |||
#ifdef __cplusplus |
@@ -39,6 +39,12 @@ usb_serial_class Serial; | |||
#endif | |||
#endif | |||
#ifdef CDC2_DATA_INTERFACE | |||
#ifdef CDC2_STATUS_INTERFACE | |||
usb_serial2_class SerialA; | |||
#endif | |||
#endif | |||
#ifdef MIDI_INTERFACE | |||
usb_midi_class usbMIDI; | |||
#endif | |||
@@ -75,7 +81,7 @@ usb_serial_class Serial; | |||
#else // F_CPU < 20 MHz | |||
#if defined(USB_SERIAL) || defined(USB_SERIAL_HID) | |||
#if defined(USB_SERIAL) || defined(USB_DUAL_SERIAL) || defined(USB_SERIAL_HID) | |||
usb_serial_class Serial; | |||
#elif (USB_DISABLED) | |||
usb_serial_class Serial; | |||
@@ -87,3 +93,5 @@ usb_seremu_class Serial; | |||
void serialEvent() __attribute__((weak)); | |||
void serialEvent() {} | |||
void serialEventA() __attribute__((weak)); | |||
void serialEventA() {} |
@@ -0,0 +1,46 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2017 PJRC.COM, LLC. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sublicense, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* 1. The above copyright notice and this permission notice shall be | |||
* included in all copies or substantial portions of the Software. | |||
* | |||
* 2. If the Software is incorporated into a build system that allows | |||
* selection among a list of target devices, then similar target | |||
* devices manufactured by PJRC.COM must be included in the list of | |||
* target devices and selectable in the same manner. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
* SOFTWARE. | |||
*/ | |||
#include "usb_dev.h" | |||
// defined by usb_dev.h -> usb_desc.h | |||
#if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE) | |||
#if F_CPU >= 20000000 | |||
#include "usb_serial_port.h" | |||
struct usb_serial_port usb_serial2_instance = { | |||
.cdc_rx_endpoint = CDC2_RX_ENDPOINT, | |||
.cdc_tx_endpoint = CDC2_TX_ENDPOINT, | |||
.cdc_tx_size = CDC2_TX_SIZE, | |||
}; | |||
#endif | |||
#endif // CDC2_STATUS_INTERFACE && CDC2_DATA_INTERFACE |
@@ -0,0 +1,48 @@ | |||
/* Teensyduino Core Library | |||
* http://www.pjrc.com/teensy/ | |||
* Copyright (c) 2017 PJRC.COM, LLC. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sublicense, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* 1. The above copyright notice and this permission notice shall be | |||
* included in all copies or substantial portions of the Software. | |||
* | |||
* 2. If the Software is incorporated into a build system that allows | |||
* selection among a list of target devices, then similar target | |||
* devices manufactured by PJRC.COM must be included in the list of | |||
* target devices and selectable in the same manner. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
* SOFTWARE. | |||
*/ | |||
#ifndef USBserial2_h_ | |||
#define USBserial2_h_ | |||
#include "usb_desc.h" | |||
#if defined(CDC2_STATUS_INTERFACE) && defined(CDC2_DATA_INTERFACE) | |||
#define USB_SERIAL_SUFFIX 2 | |||
#define SERIAL_CLASS_SUFFIX A | |||
#include "usb_serial_template.h" | |||
#define usb_cdc2_line_coding usb_serial2_instance.cdc_line_coding | |||
#define usb_cdc2_line_rtsdtr_millis usb_serial2_instance.cdc_line_rtsdtr_millis | |||
#define usb_cdc2_line_rtsdtr usb_serial2_instance.cdc_line_rtsdtr | |||
#define usb_cdc2_transmit_flush_timer usb_serial2_instance.cdc_transmit_flush_timer | |||
#endif // CDC_STATUS_INTERFACE && CDC_DATA_INTERFACE | |||
#endif // USBserial2_h_ |
@@ -110,6 +110,30 @@ | |||
#ifdef CDC_TX_SIZE | |||
#undef CDC_TX_SIZE | |||
#endif | |||
#ifdef CDC2_STATUS_INTERFACE | |||
#undef CDC2_STATUS_INTERFACE | |||
#endif | |||
#ifdef CDC2_DATA_INTERFACE | |||
#undef CDC2_DATA_INTERFACE | |||
#endif | |||
#ifdef CDC2_ACM_ENDPOINT | |||
#undef CDC2_ACM_ENDPOINT | |||
#endif | |||
#ifdef CDC2_RX_ENDPOINT | |||
#undef CDC2_RX_ENDPOINT | |||
#endif | |||
#ifdef CDC2_TX_ENDPOINT | |||
#undef CDC2_TX_ENDPOINT | |||
#endif | |||
#ifdef CDC2_ACM_SIZE | |||
#undef CDC2_ACM_SIZE | |||
#endif | |||
#ifdef CDC2_RX_SIZE | |||
#undef CDC2_RX_SIZE | |||
#endif | |||
#ifdef CDC2_TX_SIZE | |||
#undef CDC2_TX_SIZE | |||
#endif | |||
#ifdef SEREMU_INTERFACE | |||
#undef SEREMU_INTERFACE | |||
#endif |
@@ -39,6 +39,9 @@ void yield(void) | |||
if (running) return; // TODO: does this need to be atomic? | |||
running = 1; | |||
if (Serial.available()) serialEvent(); | |||
#ifdef USB_DUAL_SERIAL | |||
if (SerialA.available()) serialEventA(); | |||
#endif | |||
if (Serial1.available()) serialEvent1(); | |||
if (Serial2.available()) serialEvent2(); | |||
if (Serial3.available()) serialEvent3(); |