Browse Source

teensy3: Add support for a second USB serial port

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>
main
Geert Uytterhoeven 4 years ago
parent
commit
4148e650d0
10 changed files with 201 additions and 2 deletions
  1. +1
    -0
      teensy3/WProgram.h
  2. +13
    -1
      teensy3/usb_desc.c
  3. +35
    -0
      teensy3/usb_desc.h
  4. +18
    -0
      teensy3/usb_dev.c
  5. +4
    -0
      teensy3/usb_dev.h
  6. +9
    -1
      teensy3/usb_inst.cpp
  7. +46
    -0
      teensy3/usb_serial2.c
  8. +48
    -0
      teensy3/usb_serial2.h
  9. +24
    -0
      teensy3/usb_undef.h
  10. +3
    -0
      teensy3/yield.cpp

+ 1
- 0
teensy3/WProgram.h View File

@@ -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"

+ 13
- 1
teensy3/usb_desc.c View File

@@ -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

+ 35
- 0
teensy3/usb_desc.h View File

@@ -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

+ 18
- 0
teensy3/usb_dev.c View File

@@ -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) {

+ 4
- 0
teensy3/usb_dev.h View File

@@ -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

+ 9
- 1
teensy3/usb_inst.cpp View File

@@ -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() {}

+ 46
- 0
teensy3/usb_serial2.c View File

@@ -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

+ 48
- 0
teensy3/usb_serial2.h View File

@@ -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_

+ 24
- 0
teensy3/usb_undef.h View File

@@ -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

+ 3
- 0
teensy3/yield.cpp View File

@@ -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();

Loading…
Cancel
Save