Audio and two serials?

jerryk

Well-known member
Hello,

I'm working on a radio project with a Teensy 4.1. At the moment, I use the "dual serial" option. One serial is used for the Arduino IDE, and the second one - to remote control the radio. I'd like to have the radio also audio-communicate with my computer via the USB. In the Arduino pulldown menu,
there is "Dual Serial", and there is "Serial + midi + audio". There is no option for "Dual Serial + Audio". Is there a technical reason why that can't be done - or did the list of options just get too long? If the latter, how would I add the option I need? Don't think the radio needs midi...

Thanks in advance,

- Jerryk
 
Working on usb_desc.h. I have hijacked the TRIPLE_SERIAL entry. I had to comment out a few lines of code in yield.cpp that wanted that third serial port keying off #ifdef USB_TRIPLE_SERIAL.

Unfortunately, it doesn't work. The serial ports don't work, the audio doesn't work, Windows says "This device cannot start. (Code 10)" in Device Manager.

--------------- snip --------------------
#elif defined(USB_TRIPLE_SERIAL)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x048C
#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\

// Two serial ports plus one audio
#define NUM_ENDPOINTS 8
#define NUM_INTERFACE 5

#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 3
#define CDC_ACM_SIZE 16
#define CDC_RX_SIZE_480 512
#define CDC_TX_SIZE_480 512
#define CDC_RX_SIZE_12 64
#define CDC_TX_SIZE_12 64

#define CDC2_STATUS_INTERFACE 2 // second Serial
#define CDC2_DATA_INTERFACE 3
#define CDC2_ACM_ENDPOINT 4
#define CDC2_RX_ENDPOINT 5
#define CDC2_TX_ENDPOINT 5

// Audio
#define AUDIO_INTERFACE 4 // Audio (uses 3 consecutive interfaces)
#define AUDIO_TX_ENDPOINT 6
#define AUDIO_TX_SIZE 180
#define AUDIO_RX_ENDPOINT 6
#define AUDIO_RX_SIZE 180
#define AUDIO_SYNC_ENDPOINT 7

// #define CDC3_STATUS_INTERFACE 4 // SerialUSB2
// #define CDC3_DATA_INTERFACE 5
// #define CDC3_ACM_ENDPOINT 6
// #define CDC3_RX_ENDPOINT 7
// #define CDC3_TX_ENDPOINT 7

// first serial port
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK

//second serial port
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK

// Audio Endpoints
#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS + ENDPOINT_TRANSMIT_ISOCHRONOUS
#define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_ISOCHRONOUS
//Audio endpoints
---------------- endsnip ---------------

I note that other audio sections have a thing called "SEREMU" - Serial emulator? Is that somehow connected to the audio?
Or is it just a spare emulated serial port for whatever?

Is there something magical about the product ID? Does Windows "know" that it's supposed to be three serial ports?

- Jerryk
 
I shrunk my declarations down to just the two serial ports. It worked. I increased the number of endpoints without enabling the audio... still worked. Then when I enabled the audio - dead meat. The device unable to start, no serial ports, and I had to push
the button on the Teensy to reprogram.

Just this little section:
// Audio
#define AUDIO_INTERFACE 4 // Audio (uses 3 consecutive interfaces)
#define AUDIO_TX_ENDPOINT 6
#define AUDIO_TX_SIZE 180
#define AUDIO_RX_ENDPOINT 6
#define AUDIO_RX_SIZE 180
#define AUDIO_SYNC_ENDPOINT 7

If that's defined, it kills the entire USB composite device.
If I comment it out - without changing anything else - the composite device lives, and I have the two serial ports.

Interesting: Supposedly the audio "Uses 3 consecutive interfaces". But it only uses 2 endpoints. On endpoint for audio receive & transmit, and the other one for "audio sync". Is there an "Interface" without an endpoint?
 
Then when I enabled the audio - dead meat. The device unable to start, no serial ports, and I had to push
the button on the Teensy to reprogram.
Did you get this working? I am trying to achieve the same thing you were trying.
 
Audio takes up 3 interfaces, you have to take that into account when defining NUM_INTERFACE.
 
Audio takes up 3 interfaces, you have to take that into account when defining NUM_INTERFACE.
For a little bit of context, I'm using teensy 4.1 with PlatformIO. I tried modifying the USB_MIDI_AUDIO_SERIAL profile to work with dual usb so I wouldn't have to touch the audio mapping. I just added the cdc2 interfaces and endpoints on to the end, and I made sure to update the interface and endpoint counts and add endpoint configs. This did get the PlatformIO project to recognize SerialUSB1, but when I actually uploaded, there was no data on either of the ports.
 
One thing to note with Windows is that if you’ve ever plugged in a device with a given VID : PID combination (in this case 16C0:048C) before, it’s cached, Windows ignores any changes, and then moans it can’t start the device.

The “solution” to this is to uninstall the old device, then plug in your Teensy with the new USB descriptors.

Another solution would be to use a different PID. However, only a limited number of these make your device visible to the Teensy loader, plus only some of that limited range will work as SEREMU or MTP devices across Windows, macOS and Linux. Which PIDs do what? That’s never been documented…
 
Last edited:
I once had a solution that changed the PID every time… Unfortunately, I don't remember where or when that was… I'm sorry. But it can be done without much effort.
 
Thanks for all the replies guys! I don't actually need the MIDI part of USB_MIDI_AUDIO_SERIAL, so I got rid of it. The reason I have to use that build flag specifically is because I'm using a modified audio library (https://github.com/alex6679/teensy-4-usbAudio/tree/main/src) so I can use usb ports for audio transfer. For some reason, the USB features only work with USB_MIDI_AUDIO_SERIAL. With this in mind, I changed the block in usb_desc.h to:

#elif defined(USB_MIDI_AUDIO_SERIAL)
#define VENDOR_ID 0x16C0
#define PRODUCT_ID 0x048A
#define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'}
#define MANUFACTURER_NAME_LEN 11
#define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','I','D','I','/','A','u','d','i','o'}
#define PRODUCT_NAME_LEN 17
#define EP0_SIZE 64
#define NUM_ENDPOINTS 7
#define NUM_INTERFACE 7
#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 3
#define CDC_ACM_SIZE 16
#define CDC_RX_SIZE_480 512
#define CDC_TX_SIZE_480 512
#define CDC_RX_SIZE_12 64
#define CDC_TX_SIZE_12 64
#define CDC2_STATUS_INTERFACE 2 // SerialUSB1
#define CDC2_DATA_INTERFACE 3
#define CDC2_ACM_ENDPOINT 4
#define CDC2_RX_ENDPOINT 5
#define CDC2_TX_ENDPOINT 5
#define AUDIO_INTERFACE 4 // Audio (uses 3 consecutive interfaces)
#define AUDIO_TX_ENDPOINT 6
#define AUDIO_RX_ENDPOINT 6
#define AUDIO_SYNC_ENDPOINT 7
#define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK
#define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
#define ENDPOINT5_CONFIG ENDPOINT_RECEIVE_BULK + ENDPOINT_TRANSMIT_BULK
#define ENDPOINT6_CONFIG ENDPOINT_RECEIVE_ISOCHRONOUS + ENDPOINT_TRANSMIT_ISOCHRONOUS
#define ENDPOINT7_CONFIG ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_ISOCHRONOUS

With this setup, the USB audio features function properly, and the compiler recognizes SerialUSB1. However, when I tried using the port connected to SerialUSB1, I wasn't getting any data through. I found that I forgot to add 'while(!SerialUSB1)' after 'while(!Serial)', and I realized I could use that to diagnose if SerialUSB1 was the source of the issue. After adding that line, the program got caught, telling me it wasn't actually connecting to the port. Could this issue be related to what h4yn0nnym0u5e mentioned?

Just a something to note, besides the changes in the git repo I linked and usb_desc.h, I haven't made changes to any other file, so it could be that I'm missing something in that regard.
 
Back
Top