-
Notifications
You must be signed in to change notification settings - Fork 11
Open
Labels
bugSomething isn't workingSomething isn't working
Description
This only happens on Wokwi. It works fine with the actual hardware.
Also, everything based on ESP-IDF, ie: esp-idf-hal, ESP-IDF and the Arduino framework all work fine.
The issue is only with Rust no-std (esp-hal) on Wokwi.
Here is a minimal example to reproduce, using LEDs to debug.
It hangs at Uart::new() or possibly Config::default().
#![no_std]
#![no_main]
use esp_hal::{
clock::CpuClock,
gpio::{Level, Output, OutputConfig},
main,
time::{Duration, Instant},
uart::{Config, Uart},
};
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[main]
fn main() -> ! {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
let mut led1 = Output::new(peripherals.GPIO5, Level::High, OutputConfig::default());
let mut led2 = Output::new(peripherals.GPIO6, Level::High, OutputConfig::default());
for _ in 0..16 {
led1.toggle();
let delay_start = Instant::now();
while delay_start.elapsed() < Duration::from_millis(125) {}
}
let uart_cfg = Config::default().with_baudrate(115200);
let mut uart = Uart::new(peripherals.UART0, uart_cfg)
.unwrap()
.with_rx(peripherals.GPIO20)
.with_tx(peripherals.GPIO21);
for _ in 0..16 {
led2.toggle();
let delay_start = Instant::now();
while delay_start.elapsed() < Duration::from_millis(125) {}
}
loop {
let mut error = false;
let mut buf: [u8; 1] = [0; 1];
while uart.read_ready() {
match uart.read(&mut buf) {
Ok(_) => {
match uart.write(&buf) {
Ok(_) => (),
Err(_) => error = true,
};
}
Err(_) => {
error = true;
}
};
}
if error {
for _ in 0..16 {
led1.toggle();
led2.toggle();
let delay_start = Instant::now();
while delay_start.elapsed() < Duration::from_millis(125) {}
}
}
}
}[package]
edition = "2021"
name = "uart-example"
version = "0.1.0"
[[bin]]
name = "uart-example"
path = "./src/bin/main.rs"
[dependencies]
critical-section = "1.2.0"
esp-hal = { version = "1.0.0-beta.0", features = ["esp32c3", "unstable"] }
[profile.dev]
# Rust debug is too slow.
# For debug builds always builds with some optimization
opt-level = "s"
[profile.release]
codegen-units = 1 # LLVM can perform better optimizations using a single thread
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 's'
overflow-checks = falseprintln! is working.
You can also write directly to the UART FIFO register.
For example:
#![no_std]
#![no_main]
use esp_backtrace as _;
use esp_println::println;
use esp_hal::{clock::ClockControl, delay::Delay, peripherals::Peripherals, prelude::*};
fn uart_tx(data: u8) {
unsafe {
core::arch::asm!("mv x13, {0}", in(reg) data);
core::arch::asm!("li x12, 0x60000000");
core::arch::asm!("andi x13, x13, 255");
core::arch::asm!("sw x13, 0(x12)");
}
}
#[entry]
fn main() -> ! {
let peripherals = Peripherals::take();
let system = peripherals.SYSTEM.split();
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
let delay = Delay::new(&clocks);
loop {
for b in b"UART\n" {
uart_tx(*b);
}
delay.delay_millis(1000u32);
println!("PRINTLN");
delay.delay_millis(1000u32);
}
}The output of this code is the following:
UART
PRINTLN
UART
PRINTLN
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working