Uart Rx/tx
Uart Rx/tx
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
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
Re: Uart Rx/tx
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).
Re: Uart Rx/tx
@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?
Re: Uart Rx/tx
Hello
Did someone succeed in running serial UART by using a single wire?
Hardware and software examples are welcomed.
regards
Did someone succeed in running serial UART by using a single wire?
Hardware and software examples are welcomed.
regards
Re: Uart Rx/tx
bump, I am also trying to do this and having trouble, does anybody have any example of this?
-
- Posts: 1731
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Uart Rx/tx
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.
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.
Re: Uart Rx/tx
Thanks I appreciate this feedback, do you know if there will be any kind of line contention I would need to look out for?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.
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
-
- Posts: 1731
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Uart Rx/tx
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).
I'll dig up a bit of code.could you possibly give some example code
I feel like switching RX/TX on a single pin by reconfiguring the pin each time via the UART driver should work.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.
Probably because your TX's output level (high when idle) 'overrides' the other side's, see above.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.
-
- Posts: 1731
- Joined: Mon Oct 17, 2022 7:38 pm
- Location: Europe, Germany
Re: Uart Rx/tx
Ok, here's pieces of my code:
First, install & initialize the UART driver.
Then set up the GPIO pin:
Finally route the UART's signals to that pin:
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
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);
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);
}
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);
}
Re: Uart Rx/tx
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.
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
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 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: No registered users and 40 guests