I find I am confused by USB

jerryk

Active member
Hello,

I'm trying to implement a custom USB type for a ham radio project; I need two serial ports and an audio port. At first glance, it seems simple: Just edit boards.txt to put in the option, and edit usb_desc.h to define the new type, pulling in pieces from other types that have the ports I want.

The first snag is endpoints. Apparently, due to timing constraints having to do with 480Mbit/s support, the Teensy 4.1 can only have 8 endpoints. Endpoints 0
and 1 are reserved. That leaves 6 endpoints. Each serial port requires two endpoints - one for data, the other for control. An audio port requires 3 endpoints. That's
7 endpoints, and we only have 6.

Why does a serial port need two endpoints? Can it work with only one?

There is also "seremu", which is a serial port that only requires one endpoint. I guess it's not as good as "Serial". But it seems good enough. Remote control of a ham radio transceiver is not exactly high-impact serial.

OK, I made an entry to usb_desc.h with one real serial port ( 2 endpoints ), one seremu port ( 1 endpoint ) and an audio port ( 3 endpoints ). 6 endpoints total.

Whups, it doesn't compile. Here's where things get interesting:
There is a seremu class, but it is never instantiated. Where would it be instantiated?

Well, it looks like it would be instantiated in usb_inst.cpp. But it isn't. In fact - usb_inst.cpp does not seem to be actually compiled. I stuck syntax errors in it, and they
are never found. Why is that?
 
@jerryk: Without seeing specific examples and/or information showing where you placed your syntax errors, there are a few very likely possibilities:

1) make sure you are modifying the correct usb_inst.cpp file
a) there are separate core files for T3 & T4

2) make sure you are modifying the correct area in the correct usb_inst.cpp
a) there are several compiler/pre-processor directives in that file
i) #if F_CPU >= 20000000 (checking if the processor speed exceeds 20MHz, plus the corresponding #else[/ICODE (towards the bottom of the file) for that [ICODE]#if)
ii) I placed int abc (without a properly trailing semicolon) inside of the section (see below for specific section) that is within the #if F_CPU >= 20000000 section, and not only was it compiled, the compiler complained as expected
Code:
#ifdef SEREMU_INTERFACE
usb_seremu_class Serial;
#endif

3) Your USB TYPE includes some kind of SERIAL device . . . SEREMU is used when there are no other SERIAL ports in use

Double-check your mods to make sure that you aren't modifying the wrong place or the wrong file, but it's more than likely that #3 above is what's actually coming into play.

Hope that helps . . .

Mark J Culross
KD5RXT

P.S. For the syntax error / compiler test, I selected T4.0, USB TYPE Flight Sim Controls, and edited the file in C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4
 
Last edited:
The first snag is endpoints. Apparently, due to timing constraints having to do with 480Mbit/s support, the Teensy 4.1 can only have 8 endpoints.
This isn't true, and also note that input and output endpoints may be completely independent despite possibly sharing the same endpoint number.
 
This isn't true, and also note that input and output endpoints may be completely independent despite possibly sharing the same endpoint number.
If it isn't true that the Teensy is limited to 8, then how many endpoints can it have?
 
Because endpoints 0 and 1 are reserved, you can use up to 6 IN and 6 OUT endpoints.

In USB-speak, IN means Teensy to your PC, and OUT means your PC to Teensy.

For usb_desc.h defines, we usually call IN "transmit" or "TX" because Teensy is transmitting, and we call OUT "receive" or RX. The words in the USB standard documents are written from the PC (USB host) point of view. Usually in the USB standard the words are nouns, because the USB standard tries to describe a system. In the code which runs on Teensy, we usually use words that describe what Teensy actually does. Usually we use verb words because we're focused on actions Teensy performs.

Serial needs 2 IN and 1 OUT.

HID emulating serial needs 1 IN and 1 OUT.

Audio needs 2 IN and 1 OUT.

However, some combinations aren't well supported in practice even if they could theoretically work in terms of only endpoint allocation. That lack of support is "only" a software limitation, so there is at least some hope future software may improve the situation. The software that exists today as a lot of assumptions that could be described as "either real or emulated serial", which makes other cases like both or neither pretty difficult.

By only editing usb_desc.h, you should be able to achieve 2 Serial and 1 Audio. That combination would use all 6 IN and 3 of the 6 OUT endpoints.

Small details matter. It's easy to get something wrong. There might also be limitations of the software when you try a combination which hasn't been tested.

If those details seem hard, please consider something even harder is trying to help you when we can't even see those specific details. But we still do try. Hopefully this message to explain the limits helps? If you need more, please understand we can help you much better when we can see the problem, and best when you give enough info for us to actually reproduce the problem. Maybe consider clicking the Code </> button and copy-paste your code, or click the "Attach files" button and upload your usb_desc.h file.
 
Last edited:
Back
Top