Lowest Latency 2-way communication between T4.1 & T4.0?

Status
Not open for further replies.

sid8580

Well-known member
Hi everyone,

Anyone have an opinion on the fastest method of 2 Teensy 4.x talking to each other? I see serial & CAN bus as maybe the best options?

When I say fastest I mean latency - this project lives and dies by its reaction time, which has to remain in the <10ms range if at all possible. However it's not a ton of data we need to move. Just small messages similar to and including MIDI (one day MIDI 2.0, and maybe one day also internal control data relating to the parameters of a digital synthesizer).

Right now I'm thinking serial is simple to build, program and won't have a lot of library overhead to make it work. Any reason I *shouldn't* go that route?

Thanks!
 
10 milliseconds might as well be an eternity relative to the response speed you can achieve on these chips.

I'd go with ordinary hardware serial and use a fast baud rate like 1 or 4 Mbit. Use RS485 if the distance is more than about 1 foot.
 
+1 on serial being simple and effective. Would get more complex/interesting if you needed much faster than that. Dual ported static ram?
 
@tonton81 wrote SPI Transfer library that was super fast and great for T_3.x's - not sure it got an update for T_4.x's

But indeed simple start with UART Serial should give needed results at higher baud - at least enough to start.
 
The one potential trouble with serial on the Teensy 4.x's is you might want to use hardware flow control to make sure either buffer doesn't overflow. However, you only have 2 choices for the CTS pin:
  • Serial3 uses pin 19 for the CTS pin, which unfortunately conflicts with the first I2C bus;
  • Serial5 uses pin 35 on the Teensy 4.0 and 43 on the Teensy 4.1 for the CTS pin, which is in the middle of the pins for the micro-SD card.

According to https://forum.pjrc.com/threads/60448-Teensy-4-0-CTS-pins, you might be able to use pins 40 or 41 for Serial4.
 
T_4.x all have 64 byte Rx buffers like :: SERIAL8_RX_BUFFER_SIZE 64

Noted above that the messages are small? As long as they are promptly serviced, or enlarged as needed with "void addMemoryForRead(void *buffer, size_t length);" it should be easy to service them.
 
T_4.x all have 64 byte Rx buffers like :: SERIAL8_RX_BUFFER_SIZE 64

Noted above that the messages are small? As long as they are promptly serviced, or enlarged as needed with "void addMemoryForRead(void *buffer, size_t length);" it should be easy to service them.

Well it is the promptly serviced thing that can be an issue. IIRC, the Teensy 4.x has 4 byte hardware FIFOs on all serial UARTs. So you have to make sure that interrupts can be serviced before the 5th byte comes in.

And as you mention, there are 64 byte buffers in memory to allow for some amount of slop where the reads aren't happening fast enough, but interrupts allow the buffers to be filled with the bytes. But you do need to do the reads to clear the buffers before the 65th byte comes in.

I tend to think that ultimately you need some sort of flow control. Either things like waiting for an ACK after some amount of data is sent, or perhaps a way for the reader to say slow down, It doesn't have to be hardware flow control or even implemented in the Teensy side of things, but if you don't have automatic support, you likely will need to implement it in your own code.
 
Yes, the UART FIFOs are only 4 byte - feeding into the receive buffer - the CORES code has perhaps two bytes warning firing the interrupt so 2* 1/100,000 of a second to respond to the interrupt at 1Mbaud - then find room in the (expandable) buffer before the 5th byte completes in the next 10us.

If the interrupt isn't serviced or the buffer over fills then data could be lost. An empty sketch completes 7 to 20 million cycles /second - seems it bumped to 12+ on the low end with improved yield() present. So plenty of time/power available before loading - if loaded then attention is needed.
 
Looks like @sid8580 has not been back up here since posting... (although maybe and not logged in...)

Will be interesting to see if KISS strategy works. Unless I missed something so far all we know is he want's low latency for short messages, but not much else. Like Bidirectional? Can either side initiate the conversation or is one of them in control? How often....

Thought I would chime in here, maybe a little late, but thought I would mention, in regard to CTS... This has changed with recent release...

The one potential trouble with serial on the Teensy 4.x's is you might want to use hardware flow control to make sure either buffer doesn't overflow. However, you only have 2 choices for the CTS pin:
  • Serial3 uses pin 19 for the CTS pin, which unfortunately conflicts with the first I2C bus;
  • Serial5 uses pin 35 on the Teensy 4.0 and 43 on the Teensy 4.1 for the CTS pin, which is in the middle of the pins for the micro-SD card.
That is with the current release of Teensyduino, you can setup a CTS pin (attachCts) for any of the Hardware Serial ports to any of the XBAR pins. Likewise you can setup to use any XBAR pin as the RX pin for any hardware Serial port. However there is a restriction that you can not use XBAR pin for RX and an XBAR pin for CTS on the same Serial port.

Note: My XLS document shows the XBar pins... But here is the table in HardwareSerial.cpp which has the list:
Code:
const pin_to_xbar_info_t PROGMEM pin_to_xbar_info[] = {
	{0,  17, 1, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x1},
	{1,  16, 1, nullptr, 0},
	{2,   6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x0},
	{3,   7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x0},
	{4,   8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x0},
	{5,  17, 3, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x0},
	{7,  15, 1, nullptr, 0 },
	{8,  14, 1, nullptr, 0},
	{30, 23, 1, &IOMUXC_XBAR1_IN23_SELECT_INPUT, 0x0},
	{31, 22, 1, &IOMUXC_XBAR1_IN22_SELECT_INPUT, 0x0},
	{32, 10, 1, nullptr, 0},
	{33,  9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x0},

#ifdef ARDUINO_TEENSY41
	{36, 16, 1, nullptr, 0},
	{37, 17, 1, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x3},
	{42,  7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x1},
	{43,  6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x1},
	{44,  5, 3, &IOMUXC_XBAR1_IN05_SELECT_INPUT, 0x1},
	{45,  4, 3, &IOMUXC_XBAR1_IN04_SELECT_INPUT, 0x1},
	{46,  9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x1},
	{47,  8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x1}
#else	
	{34,  7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x1},
	{35,  6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x1},
	{36,  5, 3, &IOMUXC_XBAR1_IN05_SELECT_INPUT, 0x1},
	{37,  4, 3, &IOMUXC_XBAR1_IN04_SELECT_INPUT, 0x1},
	{38,  9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x1},
	{39,  8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x1}
#endif
Note: The first entry in each row is the Teensy pin number, the rest of each item is the configuration information for it (Which XBar item, what is the MUX value to configure to, which input select register to configure to what value to have the signal routed to that pin...)
 
Looks like @sid8580 has not been back up here since posting... (although maybe and not logged in...)

Will be interesting to see if KISS strategy works. Unless I missed something so far all we know is he want's low latency for short messages, but not much else. Like Bidirectional? Can either side initiate the conversation or is one of them in control? How often....

Thought I would chime in here, maybe a little late, but thought I would mention, in regard to CTS... This has changed with recent release...


That is with the current release of Teensyduino, you can setup a CTS pin (attachCts) for any of the Hardware Serial ports to any of the XBAR pins. Likewise you can setup to use any XBAR pin as the RX pin for any hardware Serial port. However there is a restriction that you can not use XBAR pin for RX and an XBAR pin for CTS on the same Serial port.
Cool, good to know. Thanks. More stuff to put in my ever growing spreadsheet of all Teensy pinouts. We really need to get this documented in the official documentation (and the unofficial twiki).

Of course if the message is real simple (on/off), one possibility is just use one hardware pin in each direction.
 
Looks like @sid8580 has not been back up here since posting... (although maybe and not logged in...)

Will be interesting to see if KISS strategy works. Unless I missed something so far all we know is he want's low latency for short messages, but not much else. Like Bidirectional? Can either side initiate the conversation or is one of them in control? How often....

Thought I would chime in here, maybe a little late, but thought I would mention, in regard to CTS... This has changed with recent release...

Had to step away for a few days, not for lack of interest in the responses - I appreciate the discussion this has spun up.

At first the second Teensy (the 4.0) will likely just take unidirectional orders from the first (T4.1) - it will handle generating all the visual and haptic feedback at lightning speed, turn the sensor data into MIDI (which can get pretty complex depending on what's set up in the UI) and deal with whatever overhead the chosen MIDI output medium demands (serial, USB, and MIDI over RFM69).

The communication may eventually become bi-directional because there may need to be acknowledgement of some operations. Depending on how the sensor polling, UI, and output workload is split in the future, it could become even more necessary but I doubt it'd ever turn into having to transfer huge files or stream stored audio, etc...

I was hoping the consensus would be very fast serial. That will be my first avenue when I get to that point. I may get there faster than expected since, after rewiring the project for the 4.1 (up from the 3.6)... I've used literally every single pin on the 4.1! Achievement unlocked :cool: In other words the second Teensy will be useful for more than the workload split - some output functions/pins can be migrated over, which lets me avoid adding a GPIO expander like the MCP23017 to the first.

About the pitfalls mentioned, I understand the need to avoid a buffer overflow situation and how I could end up there but didn't know about the hardware CTS pins or necessarily how that'd operate, yet. Also, what is an XBAR pin?

Thanks everyone, this is great info.
 
XBar (Actually XBARA and XBARB...) is another subsystem of the IMXRT chips. See chapters 59-61. In majority of the usage cases it is a set of glue that connects a source to a target...

But in addition there are some IO pins that can be configured to be in XBAR mode, in same ways that the pins can be configured for SPI or I2C or PWM TImer or...
My before post shows the XBar pins for T4 and T4.1... But it sometimes is easier to see it in my Extended Cards, like:
T4.1-Cardlike.jpg

and
T4-Cardlike.jpg

One of the columns in these outputs show the XBar pins (in Green). The number here is which XBar logical pin it is. So suppose you with to use Pin 2 fir CTS fir Serial1,
you can just simply do Serial1.attachCTS(2);

And the underlying HardwareSerial code will do the glue for you. Of in this case routing: XBARA1_IN_IOMUX_XBAR_INOUT06 to XBARA1_OUT_LPUART6_TRG_INPUT
...
And then the pin needs to be configured in the the right mode and registers need to be set to say that tine LPUART6 Trigger Input should be used for CTS...
 
Status
Not open for further replies.
Back
Top