Implement async uart receive

This commit is contained in:
Jakob Lechner 2025-03-12 02:29:43 +01:00
parent 91be70194c
commit a764ab89ec
5 changed files with 130 additions and 55 deletions

58
Cargo.lock generated
View file

@ -32,7 +32,6 @@ version = "0.1.0"
dependencies = [ dependencies = [
"ch32-hal", "ch32-hal",
"embassy-executor", "embassy-executor",
"embassy-time",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"fugit", "fugit",
"panic-halt", "panic-halt",
@ -43,7 +42,7 @@ dependencies = [
[[package]] [[package]]
name = "ch32-hal" name = "ch32-hal"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/ch32-rs/ch32-hal#c81d2db790cc3e02e1cd408d512be0f2b6903319" source = "git+https://github.com/ch32-rs/ch32-hal#2f176c867c6f1c152e6cec6954ebc2758b637fd1"
dependencies = [ dependencies = [
"ch32-metapac", "ch32-metapac",
"critical-section", "critical-section",
@ -70,7 +69,7 @@ dependencies = [
[[package]] [[package]]
name = "ch32-metapac" name = "ch32-metapac"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/ch32-rs/ch32-metapac?rev=43066e18cf51106dff448f679dfff368a41431d7#43066e18cf51106dff448f679dfff368a41431d7" source = "git+https://github.com/ch32-rs/ch32-metapac?rev=b1cbc7a98e43af3fd3170821654784e2c01cb26b#b1cbc7a98e43af3fd3170821654784e2c01cb26b"
dependencies = [ dependencies = [
"riscv 0.11.1", "riscv 0.11.1",
"vcell", "vcell",
@ -103,7 +102,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.85", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -114,14 +113,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn 2.0.85", "syn 2.0.100",
] ]
[[package]] [[package]]
name = "document-features" name = "document-features"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
dependencies = [ dependencies = [
"litrs", "litrs",
] ]
@ -135,6 +134,8 @@ dependencies = [
"critical-section", "critical-section",
"document-features", "document-features",
"embassy-executor-macros", "embassy-executor-macros",
"embassy-time-driver",
"embassy-time-queue-driver",
] ]
[[package]] [[package]]
@ -146,7 +147,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.85", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -166,13 +167,14 @@ dependencies = [
[[package]] [[package]]
name = "embassy-sync" name = "embassy-sync"
version = "0.6.0" version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3e0c49ff02ebe324faf3a8653ba91582e2d0a7fdef5bc88f449d5aa1bfcc05c" checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"critical-section", "critical-section",
"embedded-io-async", "embedded-io-async",
"futures-sink",
"futures-util", "futures-util",
"heapless", "heapless",
] ]
@ -325,7 +327,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.85", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -429,9 +431,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.15" version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@ -465,18 +467,18 @@ dependencies = [
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.89" version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]] [[package]]
name = "qingke" name = "qingke"
version = "0.4.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f626759202434af781f805f39816be09a9172b339eb0aabc196da7a3643a1c79" checksum = "c0230c5310b68c08a3cf8b59fbeec3e9d8e352bc6500f62cbaf9c677f42c8dfc"
dependencies = [ dependencies = [
"bit_field", "bit_field",
"critical-section", "critical-section",
@ -485,9 +487,9 @@ dependencies = [
[[package]] [[package]]
name = "qingke-rt" name = "qingke-rt"
version = "0.4.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ba184bd1b7dcf6bf79e66e89ae1fda01d23b948bbb07d0758f2aa6dc3d60c27" checksum = "b955c60adac70c6d40205b1dbe9f57e1151d06aa842069cdbaef7bc07ad283fd"
dependencies = [ dependencies = [
"qingke", "qingke",
"qingke-rt-macros", "qingke-rt-macros",
@ -495,9 +497,9 @@ dependencies = [
[[package]] [[package]]
name = "qingke-rt-macros" name = "qingke-rt-macros"
version = "0.4.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0071d24b4839b7216b43e3f113354b910c9a25bf0a3d7393a4b06df9b6747c25" checksum = "5f2ed46d18953ea5765ab26a07d1f092dffac2da1b4830c4397e02c3cec08501"
dependencies = [ dependencies = [
"proc-macro-error", "proc-macro-error",
"proc-macro2", "proc-macro2",
@ -507,9 +509,9 @@ dependencies = [
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.37" version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
@ -551,7 +553,7 @@ checksum = "f265be5d634272320a7de94cea15c22a3bfdd4eb42eb43edc528415f066a1f25"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.85", "syn 2.0.100",
] ]
[[package]] [[package]]
@ -591,9 +593,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.85" version = "2.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -602,9 +604,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.13" version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]] [[package]]
name = "vcell" name = "vcell"

View file

@ -11,25 +11,29 @@ bench = false
[dependencies] [dependencies]
panic-halt = "1.0.0" panic-halt = "1.0.0"
ch32-hal = {git = "https://github.com/ch32-rs/ch32-hal", features = [ ch32-hal = {git = "https://github.com/ch32-rs/ch32-hal", features = [
"ch32v003f4p6", "ch32v003f4p6",
"embassy", "embassy",
"time-driver-tim2",
]} ]}
qingke-rt = { version = "0.4.0", features = ["highcode"] } qingke-rt = { version = "0.5.0", features = ["highcode"] }
qingke = "0.4.0" qingke = "0.5.0"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
embassy-executor = {version = "0.6.0", features = [ embassy-executor = {version = "0.6.0", features = [
# "integrated-timers", "integrated-timers",
"arch-spin", "arch-spin",
"executor-thread", "executor-thread",
"task-arena-size-128", # or better use nightly, but fails on recent Rust versions "task-arena-size-320", # see https://docs.embassy.dev/embassy-executor/git/cortex-m/index.html#task-arena-size
]} ]}
embassy-time = { version = "0.3.0" }
fugit = "0.3.7" fugit = "0.3.7"
[profile.release]
strip = true
opt-level = "z"
lto = "fat"
[profile.dev] [profile.dev]
strip = false # symbols are not flashed to the microcontroller, so don't strip them. strip = false # symbols are not flashed to the microcontroller, so don't strip them.
lto = true
opt-level = "s" # Optimize for size. opt-level = "s" # Optimize for size.
[dev-dependencies] [dev-dependencies]

53
blinky.rs Normal file
View file

@ -0,0 +1,53 @@
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)]
use ch32_hal as hal;
use embassy_executor::Spawner;
use embassy_time::Timer;
use hal::gpio::{AnyPin, Level, Output, Pin};
use hal::println;
#[embassy_executor::task]
async fn blink(pin: AnyPin, interval_ms: u64) {
println!("blink task");
let mut led = Output::new(pin, Level::Low, Default::default());
loop {
println!("set high");
led.set_high();
Timer::after_millis(interval_ms).await;
println!("set low");
led.set_low();
Timer::after_millis(interval_ms).await;
}
}
#[embassy_executor::main(entry = "qingke_rt::entry")]
async fn main(spawner: Spawner) -> ! {
hal::debug::SDIPrint::enable();
let mut config = hal::Config::default();
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
let p = hal::init(config);
println!("CHIP signature => {}", hal::signature::chip_id().name());
println!("Clocks {:?}", hal::rcc::clocks());
// let mut led = Output::new(p.PC4, Level::Low, Default::default());
spawner.spawn(blink(p.PC3.degrade(), 1500)).unwrap();
//spawner.spawn(blink(p.PD1.degrade(), 270)).unwrap();
loop {
Timer::after_millis(1000).await;
println!("tick");
}
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
let _ = hal::println!("\n\n\n{}", info);
loop {}
}

12
memory.x Normal file
View file

@ -0,0 +1,12 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K
}
REGION_ALIAS("REGION_TEXT", FLASH);
REGION_ALIAS("REGION_RODATA", FLASH);
REGION_ALIAS("REGION_DATA", RAM);
REGION_ALIAS("REGION_BSS", RAM);
REGION_ALIAS("REGION_HEAP", RAM);
REGION_ALIAS("REGION_STACK", RAM);

View file

@ -4,27 +4,30 @@
#![feature(impl_trait_in_assoc_type)] #![feature(impl_trait_in_assoc_type)]
use ch32_hal as hal; use ch32_hal as hal;
use hal::println;
use hal::usart;
use hal::bind_interrupts; use hal::bind_interrupts;
use hal::println;
use hal::time::Hertz; use hal::time::Hertz;
use hal::timer::low_level::CountingMode; use hal::timer::low_level::CountingMode;
use hal::timer::simple_pwm::{PwmPin, SimplePwm}; use hal::timer::simple_pwm::{PwmPin, SimplePwm};
use hal::usart;
use embassy_executor::Spawner; use embassy_executor::Spawner;
bind_interrupts!(struct Irqs { bind_interrupts!(struct Irqs {
USART1 => usart::InterruptHandler<hal::peripherals::USART1>; USART1 => usart::InterruptHandler<hal::peripherals::USART1>;
}); });
const READ_BUF_SIZE: usize = 128;
#[embassy_executor::main(entry = "qingke_rt::entry")] #[embassy_executor::main(entry = "qingke_rt::entry")]
async fn main(_spawner: Spawner) -> ! { async fn main(_spawner: Spawner) -> ! {
let p = hal::init(Default::default()); hal::debug::SDIPrint::enable();
let config = hal::Config::default();
let p = hal::init(config);
let mut uart_conf = usart::Config::default(); let mut uart_conf = usart::Config::default();
uart_conf.baudrate = 19200; uart_conf.baudrate = 19200;
let mut uart = usart::Uart::new_blocking(p.USART1, p.PD5, p.PD6, uart_conf).unwrap(); let uart = usart::Uart::new(p.USART1, p.PD6, p.PD5, Irqs, p.DMA1_CH4, p.DMA1_CH5, uart_conf).unwrap(); // TX = PD5, RX = PD6
let (mut tx, mut rx) = uart.split();
uart.blocking_write(b"ready!\r\n").unwrap();
let pin_cw = PwmPin::new_ch3::<0>(p.PC3); let pin_cw = PwmPin::new_ch3::<0>(p.PC3);
let pin_ww = PwmPin::new_ch4::<0>(p.PC4); let pin_ww = PwmPin::new_ch4::<0>(p.PC4);
@ -46,26 +49,27 @@ async fn main(_spawner: Spawner) -> ! {
pwm.set_duty(ch_cw, 50); pwm.set_duty(ch_cw, 50);
pwm.enable(ch_cw); pwm.enable(ch_cw);
hal::debug::SDIPrint::enable(); let _ = tx.write(b"ready!\r\n").await;
println!("hello :)"); println!("entering main loop");
let mut rbuf: [u8; READ_BUF_SIZE] = [0u8; READ_BUF_SIZE];
let mut buffer = [0u8; 8];
loop { loop {
uart.blocking_write(b"hi!\r\n").unwrap(); println!("wfd");
match uart.blocking_read(&mut buffer) { let r = rx.read_until_idle(&mut rbuf).await;
Ok(()) => { match r {
println!("received {:#x} {:#x} {:#x} {:#x} {:#x} {:#x} {:#x} {:#x}", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7]); Ok(len) => {
} println!("got {} bytes", len);
Err(_e) => { for i in 0..len {
println!("received nothing, {:?}", _e); println!(" {}: {:#x}", i, rbuf[i]);
}
} }
Err(e) => println!("RX Error: {:?}", e),
} }
} }
} }
#[panic_handler] #[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! { fn panic(info: &core::panic::PanicInfo) -> ! {
println!("panic: {}", _info); println!("panic: {}", info);
loop {} loop {}
} }