Skip to content

Add HW DTR support (port of #2994) - #3796

Draft
i404788 wants to merge 3 commits into
esp-rs:mainfrom
i404788:rs485
Draft

Add HW DTR support (port of #2994)#3796
i404788 wants to merge 3 commits into
esp-rs:mainfrom
i404788:rs485

Conversation

@i404788

@i404788 i404788 commented Jul 15, 2025

Copy link
Copy Markdown
Contributor

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable).
  • I have used cargo xtask fmt-packages command to ensure that all changed code is formatted correctly.
  • My changes were added to the CHANGELOG.md in the proper section.
  • I have added necessary changes to user code to the Migration Guide.
  • My changes are in accordance to the esp-rs developer guidelines

Extra:

Pull Request Details 📖

Description

This is a port of #2994 for mainline (1.0.0-beta1).

Testing

Currently test it on a board to control an RS485 transceiver chip

@bugadani bugadani left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's somewhat unclear to me what we are supposed to do with ESP32 :/

Comment thread esp-hal/src/uart/mod.rs
}

/// Enable RS485 mode
pub fn with_rs485(self) -> Self {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • needs to be unstable (if you keep it)
  • should be called into_rs485 and there is no way to disable it, either (if you keep it).
  • Maybe this function should be turned into a Config struct field? All other configuration is set there.
  • I'm still not sure we want to shoehorn RS485 into the main UART driver. Given that this is pretty minor and also unstable, maybe we can, for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this function should be turned into a Config struct field? All other configuration is set there.

I don't know nearly enough about rs485, but I think I agree here. Especially when you think about how to turn it off. We already have options, like hardware flow control, which have a config setting and require pins to be passed. I think we should follow this pattern.

I'm still not sure we want to shoehorn RS485 into the main UART driver. Given that this is pretty minor and also unstable, maybe we can, for now.

I agree, that we can experiment with this as an unstable API and figure out if it needs to be a separate driver.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay apparently DTR/DSR are not available in the hardware

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All fair points, I'm currently still testing it out after porting #2994. I think putting it in the Uart driver makes sense given the reference manual, but I'm not against something like an Rs485<'a, T: Uart> but either way you need to access the Uart registers.

@github-actions github-actions Bot added the merge-conflict Merge conflict detected. Automatically added/removed by CI. label Feb 17, 2026
@github-actions

Copy link
Copy Markdown

New commits in main has made this PR unmergable. Please resolve the conflicts.

@mchodzikiewicz

mchodzikiewicz commented May 20, 2026

Copy link
Copy Markdown

Hey,

I am very interested in reviving this branch or exposing this feature anyhow, RS485 with a decent baudrate (like a standard 115200) is basically unusable without hardware direction control when using it within embassy.

I tried a bunch of stuff, like:

  • running the RS485 communication from a dedicated Interrupt executor, but flush() is completed when the FIFO is empty, so there still is one byte on the line
  • adding arbitrary block_for() to prevent yielding that flushing introduces but it is very finnicky and depends on the baudrate, parity, stopbits and the length of the message

the window to change direction is about 100us for 115200 baudrate and it is not uncommon to run smaller RS485 buses with a 1Mbit and more.

Given my prior experience with RS485 on much older chips, I guess this can also be done in software if the bare interrupt handler takes responsibility for the direction (this could be any GPIO instead of DTR then), if that's the only way to create a uniform behavior across the chip family.

I'd be happy to implement this feature in my spare time as I need this for my hobby project but let me know if it should be a config or a builder.

I am leaning slightly towards the builder pattern as you need to asign the DTR pin, since RS485 is not using DTR strictly in the same way traditional serial port uses it, it would be a leaky abstraction. Given that there are .with_tx(), with_rx(), etc, I think .with_rs485_dir() would've given me the least surprise.

(not that this is a big argument, but in fact I had a small LLM ideation session on how to hotfix my issue and it hallucinated that this method is already there)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-conflict Merge conflict detected. Automatically added/removed by CI.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants