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

#include "avr_emulation.h" #include "avr_emulation.h"
#include "usb_serial.h" #include "usb_serial.h"
#include "usb_serial2.h" #include "usb_serial2.h"
#include "usb_serial3.h"
#include "usb_seremu.h" #include "usb_seremu.h"
#include "usb_keyboard.h" #include "usb_keyboard.h"
#include "usb_mouse.h" #include "usb_mouse.h"

+ 13
- 1
teensy3/usb_desc.c View File

#define CDC2_DATA_INTERFACE_DESC_SIZE 0 #define CDC2_DATA_INTERFACE_DESC_SIZE 0
#endif #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 #ifdef MIDI_INTERFACE
#if !defined(MIDI_NUM_CABLES) || MIDI_NUM_CABLES < 1 || MIDI_NUM_CABLES > 16 #if !defined(MIDI_NUM_CABLES) || MIDI_NUM_CABLES < 1 || MIDI_NUM_CABLES > 16
#error "MIDI_NUM_CABLES must be defined between 1 to 16" #error "MIDI_NUM_CABLES must be defined between 1 to 16"
EMIT_CDC_DESCRIPTORS(CDC2), EMIT_CDC_DESCRIPTORS(CDC2),
#endif // CDC2_DATA_INTERFACE #endif // CDC2_DATA_INTERFACE


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

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

+ 46
- 0
teensy3/usb_desc.h View File

#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ONLY #define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ONLY
#define ENDPOINT7_CONFIG ENDPOINT_TRANSMIT_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) #elif defined(USB_KEYBOARDONLY)
#define VENDOR_ID 0x16C0 #define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x04D0 #define PRODUCT_ID 0x04D0

+ 18
- 0
teensy3/usb_dev.c View File

usb_cdc2_line_rtsdtr_millis = systick_millis_count; usb_cdc2_line_rtsdtr_millis = systick_millis_count;
usb_cdc2_line_rtsdtr = setup.wValue; usb_cdc2_line_rtsdtr = setup.wValue;
break; 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 #endif
} }
//serial_print("set control line state\n"); //serial_print("set control line state\n");
case CDC2_STATUS_INTERFACE: case CDC2_STATUS_INTERFACE:
dst = (uint8_t *)usb_cdc2_line_coding; dst = (uint8_t *)usb_cdc2_line_coding;
break; break;
#endif
#ifdef CDC3_STATUS_INTERFACE
case CDC3_STATUS_INTERFACE:
dst = (uint8_t *)usb_cdc3_line_coding;
break;
#endif #endif
} }
if (!dst) if (!dst)
if (t == 0) usb_serial2_flush_callback(); if (t == 0) usb_serial2_flush_callback();
} }
#endif #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 #ifdef SEREMU_INTERFACE
t = usb_seremu_transmit_flush_timer; t = usb_seremu_transmit_flush_timer;
if (t) { if (t) {

+ 4
- 0
teensy3/usb_dev.h View File

#include "usb_serial2.h" #include "usb_serial2.h"
#endif #endif


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

#else // F_CPU < 20000000 #else // F_CPU < 20000000


#ifdef __cplusplus #ifdef __cplusplus

+ 10
- 1
teensy3/usb_inst.cpp View File

#endif #endif
#endif #endif


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

#ifdef MIDI_INTERFACE #ifdef MIDI_INTERFACE
usb_midi_class usbMIDI; usb_midi_class usbMIDI;
#endif #endif


#else // F_CPU < 20 MHz #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; usb_serial_class Serial;
#elif (USB_DISABLED) #elif (USB_DISABLED)
usb_serial_class Serial; usb_serial_class Serial;
void serialEvent() {} void serialEvent() {}
void serialEventA() __attribute__((weak)); void serialEventA() __attribute__((weak));
void serialEventA() {} void serialEventA() {}
void serialEventB() __attribute__((weak));
void serialEventB() {}

+ 46
- 0
teensy3/usb_serial3.c View File

/* 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

/* 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

#ifdef CDC2_TX_SIZE #ifdef CDC2_TX_SIZE
#undef CDC2_TX_SIZE #undef CDC2_TX_SIZE
#endif #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 #ifdef SEREMU_INTERFACE
#undef SEREMU_INTERFACE #undef SEREMU_INTERFACE
#endif #endif

+ 4
- 1
teensy3/yield.cpp View File

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

Loading…
Cancel
Save