mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-30 22:01:11 +00:00

* Fix Async UART The uart handler was `writing` to the enable register instead of `modify`, which meant any wake would see the cleared enabled bit and think the event had occurred. This wasn't seen before the split of uart because it was only possible to listen to one thing at a time. This PR also removes the ReadBufferFull error in favour of returning the max bytes in the buffer. The serial examples has been updated to actually have some cross task communication. * changelog * fix dev deps
100 lines
3.0 KiB
Rust
100 lines
3.0 KiB
Rust
//! embassy serial
|
|
//!
|
|
//! This is an example of running the embassy executor and asynchronously
|
|
//! writing to and reading from uart
|
|
|
|
#![no_std]
|
|
#![no_main]
|
|
#![feature(type_alias_impl_trait)]
|
|
|
|
use embassy_executor::Spawner;
|
|
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, signal::Signal};
|
|
use esp32c2_hal::{
|
|
clock::ClockControl,
|
|
embassy,
|
|
interrupt,
|
|
peripherals::{Interrupt, Peripherals, UART0},
|
|
prelude::*,
|
|
Uart,
|
|
};
|
|
use esp_backtrace as _;
|
|
use esp_hal_common::uart::{config::AtCmdConfig, UartRx, UartTx};
|
|
use static_cell::make_static;
|
|
|
|
// rx_fifo_full_threshold
|
|
const READ_BUF_SIZE: usize = 64;
|
|
// EOT (CTRL-D)
|
|
const AT_CMD: u8 = 0x04;
|
|
|
|
#[embassy_executor::task]
|
|
async fn writer(mut tx: UartTx<'static, UART0>, signal: &'static Signal<NoopRawMutex, usize>) {
|
|
use core::fmt::Write;
|
|
embedded_io_async::Write::write(
|
|
&mut tx,
|
|
b"Hello async serial. Enter something ended with EOT (CTRL-D).\r\n",
|
|
)
|
|
.await
|
|
.unwrap();
|
|
embedded_io_async::Write::flush(&mut tx).await.unwrap();
|
|
loop {
|
|
let bytes_read = signal.wait().await;
|
|
signal.reset();
|
|
write!(&mut tx, "\r\n-- received {} bytes --\r\n", bytes_read).unwrap();
|
|
embedded_io_async::Write::flush(&mut tx).await.unwrap();
|
|
}
|
|
}
|
|
|
|
#[embassy_executor::task]
|
|
async fn reader(mut rx: UartRx<'static, UART0>, signal: &'static Signal<NoopRawMutex, usize>) {
|
|
const MAX_BUFFER_SIZE: usize = 10 * READ_BUF_SIZE + 16;
|
|
|
|
let mut rbuf: [u8; MAX_BUFFER_SIZE] = [0u8; MAX_BUFFER_SIZE];
|
|
let mut offset = 0;
|
|
loop {
|
|
let r = embedded_io_async::Read::read(&mut rx, &mut rbuf[offset..]).await;
|
|
match r {
|
|
Ok(len) => {
|
|
offset += len;
|
|
esp_println::println!("Read: {len}, data: {:?}", &rbuf[..offset]);
|
|
offset = 0;
|
|
signal.signal(len);
|
|
}
|
|
Err(e) => esp_println::println!("RX Error: {:?}", e),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[main]
|
|
async fn main(spawner: Spawner) {
|
|
esp_println::println!("Init!");
|
|
let peripherals = Peripherals::take();
|
|
let system = peripherals.SYSTEM.split();
|
|
let clocks = ClockControl::boot_defaults(system.clock_control).freeze();
|
|
|
|
#[cfg(feature = "embassy-time-systick")]
|
|
embassy::init(
|
|
&clocks,
|
|
esp32c2_hal::systimer::SystemTimer::new(peripherals.SYSTIMER),
|
|
);
|
|
|
|
#[cfg(feature = "embassy-time-timg0")]
|
|
{
|
|
let timer_group0 = esp32c2_hal::timer::TimerGroup::new(peripherals.TIMG0, &clocks);
|
|
embassy::init(&clocks, timer_group0.timer0);
|
|
}
|
|
|
|
let mut uart0 = Uart::new(peripherals.UART0, &clocks);
|
|
uart0.set_at_cmd(AtCmdConfig::new(None, None, None, AT_CMD, None));
|
|
uart0
|
|
.set_rx_fifo_full_threshold(READ_BUF_SIZE as u16)
|
|
.unwrap();
|
|
let (tx, rx) = uart0.split();
|
|
|
|
interrupt::enable(Interrupt::UART0, interrupt::Priority::Priority1).unwrap();
|
|
|
|
let signal = &*make_static!(Signal::new());
|
|
|
|
spawner.spawn(reader(rx, &signal)).ok();
|
|
spawner.spawn(writer(tx, &signal)).ok();
|
|
}
|