Uart Rx/tx

jkhax0r
Posts: 7
Joined: Mon Jan 23, 2017 6:54 am

Uart Rx/tx

Postby jkhax0r » Wed Feb 01, 2017 7:48 pm

Does anyone know if it would be possible to configure the same pin for both UART TX and UART RX simultaneously?

I have seen this feature in certain other micros and it can be used, for example, on a LIN bus or rs485 where there is a single wire/signal bus and extra error checking is not required.

I'm just running out of pins and saw this as an opportunity to save one. Thanks

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Uart Rx/tx

Postby WiFive » Thu Feb 02, 2017 3:36 am

Sure if its half duplex you just have to switch the pin to input/output during RX/tx assuming rx output of the transceiver can be tri-stated (usually with enable line).

jesseb
Posts: 29
Joined: Tue Jan 10, 2017 5:36 pm

Re: Uart Rx/tx

Postby jesseb » Thu May 03, 2018 9:35 pm

@WiFive I tried running serial UART by using a single wire but was unsuccessful by just changing direction of pin. Are there any examples on this?

michcfr
Posts: 30
Joined: Mon Jan 29, 2018 5:55 pm

Re: Uart Rx/tx

Postby michcfr » Sat Oct 23, 2021 8:57 pm

Hello
Did someone succeed in running serial UART by using a single wire?
Hardware and software examples are welcomed.

regards

realfspin
Posts: 9
Joined: Sat Apr 06, 2024 9:29 pm

Re: Uart Rx/tx

Postby realfspin » Tue May 28, 2024 3:40 am

bump, I am also trying to do this and having trouble, does anybody have any example of this?

MicroController
Posts: 1725
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Uart Rx/tx

Postby MicroController » Tue May 28, 2024 7:15 pm

You should be able to route the RX and TX signals of the UART to the same pin via the GPIO matrix (using esp_rom_gpio_connect_out_signal()/esp_rom_gpio_connect_in_signal()).

At least on a -C3 this works. Both signals can be connected to the pin alternatingly or at the same time. In the latter case you won't have to actively switch direction but you also receive an echo of every byte you send.

realfspin
Posts: 9
Joined: Sat Apr 06, 2024 9:29 pm

Re: Uart Rx/tx

Postby realfspin » Wed May 29, 2024 2:50 am

MicroController wrote: You should be able to route the RX and TX signals of the UART to the same pin via the GPIO matrix (using esp_rom_gpio_connect_out_signal()/esp_rom_gpio_connect_in_signal()).

At least on a -C3 this works. Both signals can be connected to the pin alternatingly or at the same time. In the latter case you won't have to actively switch direction but you also receive an echo of every byte you send.
Thanks I appreciate this feedback, do you know if there will be any kind of line contention I would need to look out for?

Also, if you're willing, could you possibly give some example code as I feel like I've done effectively this but at the higher level with the uart but it didn't work, I never went as low level as those apis I was just using uart_set_pin and the like.

My goal is to create a updi programmer for attiny devices out of an esp32-c3, I am able to use the c3 to listen to existing updi programmers like jtag2updi and I can see the updi commands being sent, but if I try to bring a TX line into the mix and send commands myself from the esp32 and then try to listen either one the same line or a separate pin that is connected together with the rx, no matter how I approach it I don't seem to get proper responses.

I've created my own thread here and I'm just bumping any related threads hoping to get some feedback.

https://esp32.com/viewtopic.php?f=13&t=40073

Thanks again

MicroController
Posts: 1725
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Uart Rx/tx

Postby MicroController » Wed May 29, 2024 11:11 am

realfspin wrote:
Wed May 29, 2024 2:50 am
do you know if there will be any kind of line contention I would need to look out for?
Oh yes, I forgot to mention it: Since the TX output normally actively drives the line high or low this normal setup won't work to receive data from another TX on the same line. You will have to actually reconfigure the pin between TXing (output) and RXing (input), or you can configure the pin to open-drain mode (with pull-up) (and enable both input and output on the pin).
could you possibly give some example code
I'll dig up a bit of code.
I feel like I've done effectively this but at the higher level with the uart but it didn't work, I never went as low level as those apis I was just using uart_set_pin and the like.
I feel like switching RX/TX on a single pin by reconfiguring the pin each time via the UART driver should work.
if I try to bring a TX line into the mix and send commands myself from the esp32 and then try to listen either one the same line or a separate pin that is connected together with the rx, no matter how I approach it I don't seem to get proper responses.
Probably because your TX's output level (high when idle) 'overrides' the other side's, see above.

MicroController
Posts: 1725
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Uart Rx/tx

Postby MicroController » Wed May 29, 2024 7:31 pm

Ok, here's pieces of my code:
First, install & initialize the UART driver.
Then set up the GPIO pin:

Code: Select all

const gpio_config_t pin_cfg {
	.pin_bit_mask = (1ul<<(this->pin)),
	.mode = GPIO_MODE_INPUT_OUTPUT_OD, // Input and Output w/ open-drain!
	.pull_up_en = GPIO_PULLUP_ENABLE, // Open-drain requires a pull-up.
	.pull_down_en = GPIO_PULLDOWN_DISABLE,
	.intr_type = GPIO_INTR_DISABLE
};               

gpio_config(&pin_cfg);
Finally route the UART's signals to that pin:

Code: Select all

#include "soc/uart_periph.h"
#include "esp_rom_gpio.h"

void connect_uart_to_pin() const {
  esp_rom_gpio_connect_out_signal(this->pin, UART_PERIPH_SIGNAL(this->uart.port,SOC_UART_TX_PIN_IDX), false, false);
  esp_rom_gpio_connect_in_signal(this->pin, UART_PERIPH_SIGNAL(this->uart.port,SOC_UART_RX_PIN_IDX), false);    
}  
IIRC, it is essential that the GPIO pin is set up before connecting the UART's signal(s) to it, else the GPIO setup will undo the UART signal routing.

You can disconnect the UART signals later like

Code: Select all

void connect_gpio_to_pin() const {
  // Connect RXD to "constant 1" during GPIO operation
  esp_rom_gpio_connect_in_signal(GPIO_MATRIX_CONST_ONE_INPUT, UART_PERIPH_SIGNAL(this->uart.port,SOC_UART_RX_PIN_IDX), false);
  // Connect GPIO output to pin:
  esp_rom_gpio_connect_out_signal(this->pin, SIG_GPIO_OUT_IDX, false, false);
} 

realfspin
Posts: 9
Joined: Sat Apr 06, 2024 9:29 pm

Re: Uart Rx/tx

Postby realfspin » Fri May 31, 2024 7:44 pm

Thank you tremendously, I've finally gotten some time to sit down and try this and it seems your advice has helped me gain some progress.

So, with this code below, I am able to connect both my rx and tx lines together and then connect them into an active connection from jtag2updi and snoop it's updi commands being sent while it programs an attiny. This is a step up from only being able to connect the rx line without causing (what I assume was) line contention.

I am also able to send messages on my tx line and immediately read them back on my rx line, so I feel like everything should be working...

Alas, even when I send the same commands as jtag2updi I'm apparently still not getting any response from my attiny, and of course it's hard to tell whether the problem lay in the uart setup or some detail of the updi protocol.

Code: Select all

  // UART configuration
  uart_config_t uart_config = {
  .baud_rate = UPDI_BAUD,
  .data_bits = UART_DATA_8_BITS,
  .parity = UART_PARITY_EVEN,
  .stop_bits = UART_STOP_BITS_2,
  .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
  .rx_flow_ctrl_thresh = 0,
  .source_clk = UART_SCLK_APB,
  };

  // Configure UART parameters
  uart_param_config(UPDI_UART_NUM, &uart_config);
  // Set UART pins
  uart_set_pin(UPDI_UART_NUM, UPDI_RX_PIN, UPDI_TX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
  // Install UART driver
  uart_driver_install(UPDI_UART_NUM, 1024 * 2, 0, 0, NULL, 0);

  // Set UART read timeout
  uart_set_rx_timeout(UPDI_UART_NUM, 50);
  const gpio_config_t pin_cfg {
    .pin_bit_mask = (1ul << GPIO_NUM_8) | (1ul << GPIO_NUM_2),
    .mode = GPIO_MODE_INPUT_OUTPUT_OD, // Input and Output w/ open-drain!
    .pull_up_en = GPIO_PULLUP_ENABLE, // Open-drain requires a pull-up.
    .pull_down_en = GPIO_PULLDOWN_DISABLE,
    .intr_type = GPIO_INTR_DISABLE
  };

  gpio_config(&pin_cfg);

  esp_rom_gpio_connect_out_signal(UPDI_TX_PIN, UART_PERIPH_SIGNAL(UPDI_UART_NUM, SOC_UART_TX_PIN_IDX), false, false);
  esp_rom_gpio_connect_in_signal(UPDI_RX_PIN, UART_PERIPH_SIGNAL(UPDI_UART_NUM, SOC_UART_RX_PIN_IDX), false);    
I'm assuming that at this point there's probably not much more you can do to help me, and we are probably going outside the scope of this thread. But if you do happen to have any more insight it would be greatly appreciated.

I have another thread here discussing tx/rx on the same line, although what we're doing here is effectively good enough if I can just connect two lines together.
https://esp32.com/posting.php?mode=reply&f=13&t=40073

Who is online

Users browsing this forum: Google [Bot] and 90 guests