-
Notifications
You must be signed in to change notification settings - Fork 363
Description
Bug description
In the following example, i program a esp32-none to simply echo on UART1, and my pc to alternatively send fixed size frames and wait for the echo. for any frame size under 128bytes everything is ok. above i almost systematically get FifoOverflowed on the esp32 side, despite the buffer i give for reception is big enough for the frame and the esp32 has nothing else to do.
The problem is independent of the baud rate it seems: I tested both with 1_500_00 Hz and 115_200 Hz
To Reproduce
On esp32
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]
use esp_backtrace as _;
use esp_hal::{
clock::CpuClock,
timer::timg::TimerGroup,
uart::{DataBits, Parity, StopBits},
};
use embassy_executor::Spawner;
use esp_println as _;
use log::*;
// use embedded_io_async::{Read, Write};
esp_bootloader_esp_idf::esp_app_desc!();
#[esp_rtos::main]
async fn main(_spawner: Spawner) {
// init hardware
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0);
// initialize slave
info!("setting up slave");
let config = esp_hal::uart::Config::default()
.with_baudrate(1_500_000) // same for 115_200
.with_data_bits(DataBits::_8)
.with_stop_bits(StopBits::_1)
.with_parity(Parity::Even)
;
let mut bus = esp_hal::uart::Uart::new(peripherals.UART1, config).unwrap()
.with_rx(peripherals.GPIO16)
.with_tx(peripherals.GPIO17)
.into_async();
info!("start echoing");
let mut buffer = [0; 129]; // works with 128, but not after
loop {
if let Err(err) = bus.read_exact_async(&mut buffer).await {
debug!("read error: {:?}", err);
continue
}
bus.write_async(&buffer).await.unwrap();
}
}on my pc
use std::time::{Duration, Instant};
use serial2_tokio::{SerialPort, CharSize, StopBits, Parity};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
#[tokio::main]
async fn main() {
pretty_env_logger::init();
// initialize a master on some uart port
println!("creating master");
// possible baud rates
// 115_200
// 1_000_000
// 1_500_000
// 2_000_000
let mut bus = SerialPort::open("/dev/ttyUSB1", |mut settings: serial2_tokio::Settings| {
settings.set_raw();
settings.set_baud_rate(1_500_000)?;
settings.set_char_size(CharSize::Bits8);
settings.set_stop_bits(StopBits::One);
settings.set_parity(Parity::Even);
Ok(settings)
}).unwrap();
println!("running");
let mut send = [0; 129]; // must match the buffer size on the esp32
let mut receive = send.clone();
let timeout = Duration::from_millis(100);
while tokio::time::timeout(timeout, bus.read_exact(&mut receive)).await.is_ok() {}
for j in 0 .. 20 {
send[0] = j as u8;
for i in 1 .. send.len() {send[i] = i as u8;}
let start = Instant::now();
bus.write(&send).await.unwrap();
let result = tokio::time::timeout(timeout, bus.read_exact(&mut receive)).await;
let complete_read = start.elapsed();
// if result.is_ok() {
// println!(" send {:?}", &send);
// println!(" receive {:?}", &receive);
// }
println!("elapsed {:?} result {:?} equal: {}", complete_read, result.map(|_| ()), send == receive);
}
}When the frame has 129 bytes or above get on the pc side
creating master
running
elapsed 101.528823ms result Err(Elapsed(())) equal: false
elapsed 100.536611ms result Err(Elapsed(())) equal: false
elapsed 101.556393ms result Err(Elapsed(())) equal: false
elapsed 100.579971ms result Err(Elapsed(())) equal: false
...
and on esp32 side (UART0)
INFO - setting up slave
INFO - start echoing
DEBUG - read error: FifoOverflowed
Expected behavior
When frame is 128 bytes or below I get on pc side:
creating master
running
elapsed 2.411464ms result Ok(()) equal: true
elapsed 2.270754ms result Ok(()) equal: true
elapsed 2.279125ms result Ok(()) equal: true
elapsed 2.354754ms result Ok(()) equal: true
...
Environment
-
Target device:
Chip type: esp32 (revision v1.0)
Crystal frequency: 40 MHz
Flash size: 4MB
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
MAC address: 24:6f:28:be:3e:d4
Security features: None -
Crate name and version: esp-hal 1.0.0 unstable
esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32"] } esp-hal = { version = "1.0.0", features = ["esp32", "unstable"] } esp-backtrace = { version = "0.18", features = ["esp32", "println", "colors", "panic-handler"]} esp-rtos = { version = "0.2", features = ["esp32", "embassy"] } esp-println = { version = "0.16.1", features = ["esp32", "log-04"] } esp-alloc = { version = "0.9", features = ["esp32"] }
-
UART bridge on pc side: QinHeng Electronics CH340 serial converter
Metadata
Metadata
Assignees
Labels
Type
Projects
Status