Serial 7 and 8 do not have same behavior as Serial 1 2 when identical design is used.

newbiejl

New member
Hi, newbie here. I'm trying to use Teensy 4.1 to perform some UART serial communication task.

The schematic is shown as below
UART.jpg

To verify my design, I wrote a simple code to transmit data via Teensy and measure the voltage at the other end.

Source Code
void setup() {
pinMode(1, OUTPUT);
pinMode(8, OUTPUT);
pinMode(35, OUTPUT);
pinMode(29, OUTPUT);
}

void loop() {

digitalWrite(1, HIGH);
digitalWrite(8, HIGH);
digitalWrite(35, HIGH);
digitalWrite(29, HIGH);
delay(1000);
digitalWrite(1, LOW);
digitalWrite(8, LOW);
digitalWrite(35, LOW);
digitalWrite(29, LOW);
delay(1000);
}


But only Serial 1 and 2 are working as expected. 7 and 8 is not working as the voltage measured is about 2.1V instead of toggling between 3.3 and 0V.
I have no idea why the identical design could provide different behaviors from the other end.

Without the digital isolator, all the serial are working as expected.
I was wondering is it because of the strong pullup(s) being used (100ohm) causing the issue, but why is it happened on both serial 7 and 8 only? I couldn't find any specific reason to this and thats why I'm here to seek help from experts
: )


Remarks:
RxTx are connected to Teensy
Tx out are used to measured the voltage
3v3 is connect below pin12 of teensy
 
All 8 UART Serial ports have been tested to work. Just cross Rx to Tx on same or any other port, or to a second T_4.1 and write a sketch that properly reads Rx on each and does something on Tx to feed another port or record reception.

No external pullup or other are needed in that case, just connecting wires. When connected the default UART state will show the Tx pins pulled high at 3.3V according to UART spec of Stop bit, that drops to 0V for Start. This after using Serial[1-8].begin( baud );
 
Sorry I am probably missing something: Where is Serial ports used here?

All I see are digitalWrites?
 
Sorry, I guess the title is a little bit confusing here.

You can assume that I'm testing my design (signal isolator with pullup) by toggling High/Low on those specific digital pin.

Just wondering is there any design error causing my Tx7 Out and Tx8 Out not to toggle between 3.3 and 0V?
 
Sorry I am a software guy and not EE, but maybe the resistors are causing too much current to be used causing voltage drop. Maybe your second setup has hardware issue? Like shorts or bad solder or ???
Maybe something else random on board.

Again, I know not much help.
 
When I searched for DSE [Drive Strength] in C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4\HardwareSerial.cpp, I found this:

PinDriveStrength2.jpg

Some pins are apparently set to DSE value 3 and some to DSE value 7? But I can't directly tell from the code which exact pin numbers... Sorry, I am an EE, not a software guy...

PinDriveStrength.PNG

Perhaps that explains why Tx7 and Tx8 are not working?

Paul
 
When I searched for DSE [Drive Strength] in C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy4\HardwareSerial.cpp, I found this:

View attachment 29333

Some pins are apparently set to DSE value 3 and some to DSE value 7? But I can't directly tell from the code which exact pin numbers... Sorry, I am an EE, not a software guy...

View attachment 29334

Perhaps that explains why Tx7 and Tx8 are not working?

Paul

As the CS type ;)

The begin code for SerialX ports all use the same code. Yes there are some cases, in the begin code if you are using HALF Duplex versus Full Duplex. And the configuration for RX pin is different than the TX pin.

Code:
void HardwareSerial::begin(uint32_t baud, uint16_t format)
{
...
	// Maybe different pin configs if half duplex
	half_duplex_mode_ = (format & SERIAL_HALF_DUPLEX) != 0;
	if (!half_duplex_mode_)  {
		*(portControlRegister(hardware->rx_pins[rx_pin_index_].pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;
		*(portConfigRegister(hardware->rx_pins[rx_pin_index_].pin)) = hardware->rx_pins[rx_pin_index_].mux_val;
		if (hardware->rx_pins[rx_pin_index_].select_input_register) {
		 	*(hardware->rx_pins[rx_pin_index_].select_input_register) =  hardware->rx_pins[rx_pin_index_].select_val;		
		}	

		*(portControlRegister(hardware->tx_pins[tx_pin_index_].pin)) =  IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
		*(portConfigRegister(hardware->tx_pins[tx_pin_index_].pin)) = hardware->tx_pins[tx_pin_index_].mux_val;
	} else {
		// Half duplex maybe different pin pad config like PU...		
		*(portControlRegister(hardware->tx_pins[tx_pin_index_].pin)) =  IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) 
				| IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3);
		*(portConfigRegister(hardware->tx_pins[tx_pin_index_].pin)) = hardware->tx_pins[tx_pin_index_].mux_val;
	}
...
};
But again his test code in this thread, is not using Serial.begin. Instead, it is using: pinMode(pin, OUTPUT);
And PinMode has its own rules on how to configure the pins.
 
I tried connecting four 100 ohm pullup resistors to a Teensy 4.1 running the code from msg #1, but I was unable to reproduce this problem.

Here is the hardware on my workbench.

100ohm.jpg
(click for full size)

And here are the (very slow) waveforms my oscilloscope sees.

file.png
(click for full size)

The result on channel 4, which is Teensy 4.1 pin 35, differs slightly with 3.3V peak rather than 3.4V peak. But it's nothing like 3.3V vs 2.1V as reported in msg #1. Those peak numbers could just be small overshoot (which can't be rendered on this very slow horizontal time scale, but the scope probably sees it). You can see in the photo I didn't bother to rig up a short ground leads, so a little overshoot can be expected. I did configure all 4 channels in bandwidth limit mode, since this is such a slow waveform. You can visually see all 4 waveforms look to be the same amplitude.

Perhaps the different voltage you're seeing on pins 29 & 35 could be due to different circuitry connected? Have you tested with only 100 ohm resistors and nothing else connected, like in my photo?
 
In fact I've used the same designed as attached on #1 with Teensy 3.6, The UARTs were working when the pullup is 10k.

In Teensy 4.1, I made mistake by using the pullup as 100ohm instead.
Without nothing else connected, TX7 and TX8 works fine, but with the isolators, Tx7/8 failed

[The circuitry on #1 is currently mounted on PCBA now..]
 
Not sure how much additional suggestions we can make to resolve.

But to reiterate: Maybe the drive strength to the pins might help (or not).

pinMode(pin, OUTPUT) does not configure the pins the same as SerialX.begin()

The pinMode does: *(p->pad) = IOMUXC_PAD_DSE(7);

The TX pin in SerialX.begin() does:
*(portControlRegister(hardware->tx_pins[tx_pin_index_].pin)) = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);


Now as to exactly how DSE works...
Code:
Drive Strength Field
Select one out of next values for pad: GPIO_EMC_31
000 DSE_0_output_driver_disabled — output driver disabled;
001 DSE_1_R0_150_Ohm_3_3V_260_Ohm_1_8V — R0(150 Ohm @ 3.3V, 260 Ohm@1.8V)
010 DSE_2_R0_2 — R0/2
011 DSE_3_R0_3 — R0/3
100 DSE_4_R0_4 — R0/4
101 DSE_5_R0_5 — R0/5
110 DSE_6_R0_6 — R0/6
111 DSE_7_R0_7 — R0/7
This is the data from the IMXRT reference manual for one of the IO pins.
(Page 612 in the version of the RM I am looking at)

Their descriptions are sometimes clear as mud to me. But I believe lower numbers give more strength... Except of course, 0 which is disabled.
But could be completely opposite.

But I would try setting the IO pins to different strength and see if it helps.
like:
Code:
    pinMode(29, OUTPUT);
    *(portControlRegister(29)) =  IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
Note: This is setup like the TX pin would be.
You might then try different DSE values like 2 and see if it makes any difference...
 
But I believe lower numbers give more strength...

PinDriveStrength.PNG

I think it's the other way around: the higher the number, the lower the output impedance hence the ability to source more current...
Anyway, best to try different DSE values.

Paul
 
Back
Top