Browse Source

teensy3: Add support for a third USB serial port

Add support for a triple serial port configuration (USB_TRIPLE_SERIAL),
providing a composite USB device, comprised of three serial ports.
The third serial port is called usb_serial3 (C) or SerialB (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. 0.5 KiB (despite needing 720 more
bytes for USB buffers, as gcc-5.4.1 no longer decides to unroll a loop
over all endpoints in usb_isr()).

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
teensy4-core
Geert Uytterhoeven 5 years ago
parent
commit
b515629a87
10 changed files with 214 additions and 3 deletions
  1. +1
    -0
      teensy3/WProgram.h
  2. +13
    -1
      teensy3/usb_desc.c
  3. +46
    -0
      teensy3/usb_desc.h
  4. +18
    -0
      teensy3/usb_dev.c
  5. +4
    -0
      teensy3/usb_dev.h
  6. +10
    -1
      teensy3/usb_inst.cpp
  7. +46
    -0
      teensy3/usb_serial3.c
  8. +48
    -0
      teensy3/usb_serial3.h
  9. +24
    -0
      teensy3/usb_undef.h
  10. +4
    -1
      teensy3/yield.cpp

+ 1
- 0
teensy3/WProgram.h View File

@@ -53,6 +53,7 @@
#include "avr_emulation.h"
#include "usb_serial.h"
#include "usb_serial2.h"
#include "usb_serial3.h"
#include "usb_seremu.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"

+ 13
- 1
teensy3/usb_desc.c View File

@@ -491,7 +491,14 @@ static uint8_t flightsim_report_desc[] = {
#define CDC2_DATA_INTERFACE_DESC_SIZE 0
#endif

#define MIDI_INTERFACE_DESC_POS CDC2_DATA_INTERFACE_DESC_POS+CDC2_DATA_INTERFACE_DESC_SIZE
#define CDC3_DATA_INTERFACE_DESC_POS CDC2_DATA_INTERFACE_DESC_POS+CDC2_DATA_INTERFACE_DESC_SIZE
#ifdef CDC3_DATA_INTERFACE
#define CDC3_DATA_INTERFACE_DESC_SIZE 8 + 9+5+5+4+5+7+9+7+7
#else
#define CDC3_DATA_INTERFACE_DESC_SIZE 0
#endif

#define MIDI_INTERFACE_DESC_POS CDC3_DATA_INTERFACE_DESC_POS+CDC3_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"
@@ -690,6 +697,11 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
EMIT_CDC_DESCRIPTORS(CDC2),
#endif // CDC2_DATA_INTERFACE

#ifdef CDC3_DATA_INTERFACE
EMIT_CDC_IAD_DESCRIPTOR(CDC3),
EMIT_CDC_DESCRIPTORS(CDC3),
#endif // CDC3_DATA_INTERFACE

#ifdef MIDI_INTERFACE
// Standard MS Interface Descriptor,
9, // bLength

+ 46
- 0
teensy3/usb_desc.h View File

@@ -175,6 +175,52 @@ let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports
#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT7_CONFIG ENDPOINT_TRANSMIT_ONLY

#elif defined(USB_TRIPLE_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 {'T','r','i','p','l','e',' ','S','e','r','i','a','l'}
#define PRODUCT_NAME_LEN 13
#define EP0_SIZE 64
#define NUM_ENDPOINTS 10
#define NUM_USB_BUFFERS 32
#define NUM_INTERFACE 6
#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 CDC3_STATUS_INTERFACE 4 // SerialB
#define CDC3_DATA_INTERFACE 5
#define CDC3_ACM_ENDPOINT 8
#define CDC3_RX_ENDPOINT 9
#define CDC3_TX_ENDPOINT 10
#define CDC3_ACM_SIZE 16
#define CDC3_RX_SIZE 64
#define CDC3_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
#define ENDPOINT8_CONFIG ENDPOINT_TRANSMIT_ONLY
#define ENDPOINT9_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT10_CONFIG ENDPOINT_TRANSMIT_ONLY

#elif defined(USB_KEYBOARDONLY)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x04D0

+ 18
- 0
teensy3/usb_dev.c View File

@@ -366,6 +366,12 @@ static void usb_setup(void)
usb_cdc2_line_rtsdtr_millis = systick_millis_count;
usb_cdc2_line_rtsdtr = setup.wValue;
break;
#endif
#ifdef CDC3_STATUS_INTERFACE
case CDC3_STATUS_INTERFACE:
usb_cdc3_line_rtsdtr_millis = systick_millis_count;
usb_cdc3_line_rtsdtr = setup.wValue;
break;
#endif
}
//serial_print("set control line state\n");
@@ -619,6 +625,11 @@ static void usb_control(uint32_t stat)
case CDC2_STATUS_INTERFACE:
dst = (uint8_t *)usb_cdc2_line_coding;
break;
#endif
#ifdef CDC3_STATUS_INTERFACE
case CDC3_STATUS_INTERFACE:
dst = (uint8_t *)usb_cdc3_line_coding;
break;
#endif
}
if (!dst)
@@ -925,6 +936,13 @@ void usb_isr(void)
if (t == 0) usb_serial2_flush_callback();
}
#endif
#ifdef CDC3_DATA_INTERFACE
t = usb_cdc3_transmit_flush_timer;
if (t) {
usb_cdc3_transmit_flush_timer = --t;
if (t == 0) usb_serial3_flush_callback();
}
#endif
#ifdef SEREMU_INTERFACE
t = usb_seremu_transmit_flush_timer;
if (t) {

+ 4
- 0
teensy3/usb_dev.h View File

@@ -118,6 +118,10 @@ extern void usb_touchscreen_update_callback(void);
#include "usb_serial2.h"
#endif

#ifdef CDC3_DATA_INTERFACE
#include "usb_serial3.h"
#endif

#else // F_CPU < 20000000

#ifdef __cplusplus

+ 10
- 1
teensy3/usb_inst.cpp View File

@@ -45,6 +45,12 @@ usb_serial2_class SerialA;
#endif
#endif

#ifdef CDC3_DATA_INTERFACE
#ifdef CDC3_STATUS_INTERFACE
usb_serial3_class SerialB;
#endif
#endif

#ifdef MIDI_INTERFACE
usb_midi_class usbMIDI;
#endif
@@ -81,7 +87,8 @@ usb_serial_class Serial;

#else // F_CPU < 20 MHz

#if defined(USB_SERIAL) || defined(USB_DUAL_SERIAL) || defined(USB_SERIAL_HID)
#if defined(USB_SERIAL) || defined(USB_DUAL_SERIAL) || \
defined(USB_TRIPLE_SERIAL) || defined(USB_SERIAL_HID)
usb_serial_class Serial;
#elif (USB_DISABLED)
usb_serial_class Serial;
@@ -95,3 +102,5 @@ void serialEvent() __attribute__((weak));
void serialEvent() {}
void serialEventA() __attribute__((weak));
void serialEventA() {}
void serialEventB() __attribute__((weak));
void serialEventB() {}

+ 46
- 0
teensy3/usb_serial3.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(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE)

#if F_CPU >= 20000000
#include "usb_serial_port.h"

struct usb_serial_port usb_serial3_instance = {
.cdc_rx_endpoint = CDC3_RX_ENDPOINT,
.cdc_tx_endpoint = CDC3_TX_ENDPOINT,
.cdc_tx_size = CDC3_TX_SIZE,
};
#endif

#endif // CDC3_STATUS_INTERFACE && CDC3_DATA_INTERFACE

+ 48
- 0
teensy3/usb_serial3.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 USBserial3_h_
#define USBserial3_h_

#include "usb_desc.h"

#if defined(CDC3_STATUS_INTERFACE) && defined(CDC3_DATA_INTERFACE)
#define USB_SERIAL_SUFFIX 3
#define SERIAL_CLASS_SUFFIX B

#include "usb_serial_template.h"

#define usb_cdc3_line_coding usb_serial3_instance.cdc_line_coding
#define usb_cdc3_line_rtsdtr_millis usb_serial3_instance.cdc_line_rtsdtr_millis
#define usb_cdc3_line_rtsdtr usb_serial3_instance.cdc_line_rtsdtr
#define usb_cdc3_transmit_flush_timer usb_serial3_instance.cdc_transmit_flush_timer
#endif // CDC_STATUS_INTERFACE && CDC_DATA_INTERFACE

#endif // USBserial3_h_

+ 24
- 0
teensy3/usb_undef.h View File

@@ -134,6 +134,30 @@
#ifdef CDC2_TX_SIZE
#undef CDC2_TX_SIZE
#endif
#ifdef CDC3_STATUS_INTERFACE
#undef CDC3_STATUS_INTERFACE
#endif
#ifdef CDC3_DATA_INTERFACE
#undef CDC3_DATA_INTERFACE
#endif
#ifdef CDC3_ACM_ENDPOINT
#undef CDC3_ACM_ENDPOINT
#endif
#ifdef CDC3_RX_ENDPOINT
#undef CDC3_RX_ENDPOINT
#endif
#ifdef CDC3_TX_ENDPOINT
#undef CDC3_TX_ENDPOINT
#endif
#ifdef CDC3_ACM_SIZE
#undef CDC3_ACM_SIZE
#endif
#ifdef CDC3_RX_SIZE
#undef CDC3_RX_SIZE
#endif
#ifdef CDC3_TX_SIZE
#undef CDC3_TX_SIZE
#endif
#ifdef SEREMU_INTERFACE
#undef SEREMU_INTERFACE
#endif

+ 4
- 1
teensy3/yield.cpp View File

@@ -39,8 +39,11 @@ void yield(void)
if (running) return; // TODO: does this need to be atomic?
running = 1;
if (Serial.available()) serialEvent();
#ifdef USB_DUAL_SERIAL
#if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL)
if (SerialA.available()) serialEventA();
#endif
#ifdef USB_TRIPLE_SERIAL
if (SerialB.available()) serialEventB();
#endif
if (Serial1.available()) serialEvent1();
if (Serial2.available()) serialEvent2();

Loading…
Cancel
Save