esp-idf-hal
esp-idf-hal copied to clipboard
Example uart_loopback does not compile. TX buffer managment in Uart is broken sending garbage characters.
The example https://github.com/esp-rs/esp-idf-hal/blob/master/examples/uart_loopback.rs fails to compile due to a missing import. I adapted it to my needs and fixed a couple errors so it both compiles and provides proper response when tested with linux screen.
As shown below the two commented lines to uart.write() and uart_wait_tx_done() end up causing 1 character followed by 10 garbage characters. When the write is replaced with write_nb() which does not use the uart tx buffer it works correctly.
I would greatly appreciate the proper esp_idf_hal example code to reset the watchdog timer at the bottom of the loop so I can remove the sleep_ms(15). I know that we can do this with async or threads but what I really want here is a demonstration of a fast polling loop. I find they scale better and provide more predictable timing than spawning a bunch of threads.
### Results working copied from linux screen correctly echoing keys hit from linux screen connected as uart device on other end
abcdefghijklmnopaewwabcdefghijklmnopabcdefg
### Results copied from linux screen when the write() is used instead of write_nb()
�������������b����������c�555555555�MMMMMMMMMM���555555555�����������e�555555555�����������e������������d����������f�55555555��55555555555555�������i����������j����������k����������l����������m����������n�55555555��SSSSSSSSSSSSSS����������������aSSSSSSSSSSSSSS
��555555555쪪��������c�555555555�����������a�55555555��555555555������������a����������b�55555555��MMMMMMMMMMMMMm��555555555�����������a�555555555�SSSSSSSSSSSS������������d����������e55555555555555�����������g�555555555�������iSSSSSSSSSSSS�����������k�555555555�55555555555������������n����������o�555555555����������
Source that works correctly
//! Non Blocking fast poll Uart RS485 1/2 duplex echo for RS485 style transciever
//! test
//!
//! Folowing pins are used:
//! TX GPIO43
//! RX GPIO44
//!//!
//! This example transfers data via UART.
//! Connect TX and RX pins to see the outgoing data is read as incoming data.
//! Echo characters sent from terminal such as linux screen.
#![allow(unused_imports)]
#![allow(dead_code)]
use anyhow::Result;
use esp_idf_hal::delay::NON_BLOCK;
use esp_idf_hal::gpio;
use esp_idf_hal::gpio::PinDriver;
use esp_idf_hal::delay::Delay;
use esp_idf_hal::peripherals::Peripherals;
use esp_idf_hal::prelude::*;
use esp_idf_hal::uart::*;
use esp_idf_sys;
// TODO: Figure out how to make WDT work esp_idf_hal https://github.com/esp-rs/esp-hal/blob/main/examples/src/bin/watchdog.rs
// Until then disable WDT in menu config
fn main() -> anyhow::Result<()> {
esp_idf_hal::sys::link_patches();
let peripherals = Peripherals::take()?;
let tx = peripherals.pins.gpio43;
let rx = peripherals.pins.gpio44;
let led_pin = peripherals.pins.gpio11;
let rs_48_en_pin = peripherals.pins.gpio21;
let delay: Delay = Default::default();
let mut led = PinDriver::output(led_pin)?;
let mut rs48_enable = PinDriver::output(rs_48_en_pin)?;
println!("Starting UART loopback test");
let config = config::Config::new().baudrate(Hertz(115_200));
let uart = UartDriver::new(
peripherals.uart1,
tx,
rx,
Option::<gpio::Gpio0>::None,
Option::<gpio::Gpio1>::None,
&config,
)?;
loop {
let mut buf = [0_u8; 1];
uart.read(&mut buf, NON_BLOCK)?;
// we know read will return a 0 in buf
// when nothing is available so we ignore
if buf[0] != 0 {
println!("Written 0xaa, read {:?} {:?} 0x{:02x}", buf[0] as char, buf[0],buf[0]);
rs48_enable.set_high()?;
delay.delay_us(150); // need to allow transceiver time to enter active mode
// Calling Write directly causes mutliple garbage characters to
// be sent. I think the uart is not properly managing it's buffer.
//uart.write(&buf)?;
//uart.wait_tx_done(150);
uart.write_nb(&mut buf)?;
delay.delay_ms(1);
//buf[0] = 0;
rs48_enable.set_low()?;
led.toggle()?;
}
// Only need this delay because watchdog fires otherwise
delay.delay_ms(18); // TODO: TO RESET WATCHDOG IN TIGHT LOOP LIKE THIS USING esp_idf_hal
// TODO: DO SOME OTHER WORK SINCE WE ARE NO LONGER BLOCKING
// ON DATA IN UART AVAILABILITY
}
}
### Cargo for this file
[package] name = "ex-uart-non-block-rs485" version = "0.1.0" authors = ["joe ellsworth [email protected]"] edition = "2021" resolver = "2" rust-version = "1.71"
[profile.release] opt-level = "s"
[profile.dev] debug = true # Symbols are nice and they don't increase the size on Flash opt-level = "z"
[features] default = ["std", "embassy", "esp-idf-svc/native"]
pio = ["esp-idf-svc/pio"] std = ["alloc", "esp-idf-svc/binstart", "esp-idf-svc/std"] alloc = ["esp-idf-svc/alloc"] nightly = ["esp-idf-svc/nightly"] experimental = ["esp-idf-svc/experimental"] embassy = ["esp-idf-svc/embassy-sync", "esp-idf-svc/critical-section", "esp-idf-svc/embassy-time-driver"]
[dependencies] log = { version = "0.4", default-features = false } esp-idf-svc = { version = "0.48", default-features = false } esp-idf-hal = "0.43.1" anyhow = "1.0.82" esp-idf-sys = "0.34.1"
[build-dependencies] embuild = "0.31.3"
jesse how do I tell what should be filed here or over in esp-rs. This is the second one of my issues you had to move.