esp-rs / esp-idf-hal

embedded-hal implementation for Rust on ESP32 and ESP-IDF
https://docs.esp-rs.org/esp-idf-hal/
Apache License 2.0
421 stars 171 forks source link

[Add] UART RS485 mode #447

Closed xiaguangbo closed 5 days ago

xiaguangbo commented 2 weeks ago

RTS for RS485 Half-Duplex Mode manages DE/~RE, tested

in esp-idf-hal/src/uart.rs: fn new_common

... 
esp!(unsafe {
        uart_driver_install(
            UART::port(),
            if rx.is_some() {
                config.rx_fifo_size as _
            } else {
                0
            },
            if tx.is_some() {
                config.tx_fifo_size as _
            } else {
                0
            },
            config.queue_size as _,
            queue.map(|q| q as *mut _).unwrap_or(ptr::null_mut()),
            InterruptType::to_native(config.intr_flags) as i32,
        )
    })?;

    esp!(unsafe {uart_set_mode(UART::port(), uart_mode_t_UART_MODE_RS485_HALF_DUPLEX)})?; // add this

    // Configure interrupts after installing the driver
    // so it won't get overwritten.
    let usr_intrs = config.event_config.clone().into();
    esp!(unsafe { uart_intr_config(UART::port(), &usr_intrs as *const _) })?;
... 
Vollbrecht commented 1 week ago

If you want to work on RS485 support in the public API feel free to send a PR. Though we have to be mindful to not break the usage for everyone else.

xiaguangbo commented 1 week ago

@Vollbrecht update, https://github.com/esp-rs/esp-idf-hal/pull/456

DaneSlattery commented 3 days ago

@xiaguangbo thank you for this, I was manually toggling the direction pin on an RS485 driver before this.

Is it possible to use a different pin for this?

xiaguangbo commented 3 days ago

@xiaguangbo thank you for this, I was manually toggling the direction pin on an RS485 driver before this.

Is it possible to use a different pin for this?

The master has merge last change, If crate.io esp-idf-hal not update: copy master src/uart.rs cover local code, cleaned rebuild Link this, rts/dir can be any pin.

let uart = UartDriver::new(
                            peripherals.uart1,
                            peripherals.pins.gpio5,
                            peripherals.pins.gpio6,
                            Option::<AnyIOPin>::None,
                            Some(peripherals.pins.gpio7), // rts/dir
                            &config::Config::new()
                                .mode(config::Mode::RS485HalfDuplex)
                                .baudrate(baudrate),
                        );