iTranslated by AI
Using ch32v00x-hal with CH32V003J4M6 Microcontroller
In the sample from Blinking an LED with Rust on a CH32V003J4M6 Microcontroller, I was manipulating memory directly.
This time, I tried using ch32v00x-hal, which is a HAL for the CH32V00X series.
Changes to Cargo.toml
[dependencies]
ch32v-rt = "0.0.3"
ch32v00x-hal = { version = "0.1.0", git = "https://github.com/ch32-rs/ch32v00x-hal.git", default-features = false, features = ["ch32v003j4m6"] }
Previously, I specified the riscv-rt crate, but I have changed it to ch32v-rt.
Looking at https://github.com/ch32-rs/ch32v-rt, it seems this is already deprecated and it says to use qingke-rt instead. I plan to try that out later.
Since ch32v00x-hal is not yet available on crates.io, I am using the version directly from the repository (a0a0500).
While it would likely work with default features, I specified more accurate ones.
Changes to the Build Process
Since ch32v00x-hal handles build.rs and memory.x internally, I deleted those files and added the following configuration.
[target.riscv32ec-unknown-none-elf]
rustflags = [
"-C", "link-arg=-Tlink.x",
]
Additionally, previously I was building with:
$ cargo +custom-rv32ec build
However, by running
$ rustup override set custom-rv32ec
within the project directory, I can now simply use
$ cargo build
(I'm not entirely sure why this works.)
Improved Flashing
In the previous article, I used a tool called minichlink, but I have switched to wlink provided by ch32-rs.
$ cargo install --git https://github.com/ch32-rs/wlink
[target.riscv32ec-unknown-none-elf]
runner = "wlink -v flash"
This allows flashing and execution directly from the IDE.
Changes to the Source Code
#![no_std]
#![no_main]
use ch32v_rt::entry;
use ch32v00x_hal::prelude::*;
use ch32v00x_hal::pac::Peripherals;
use panic_halt as _;
#[entry]
fn main() -> ! {
let pac = Peripherals::take().unwrap();
let mut rcc = pac.RCC.constrain();
let _clocks = rcc.config.freeze();
let gpioc = pac.GPIOC.split(&mut rcc);
let mut led = gpioc.pc1.into_push_pull_output();
loop {
led.toggle();
for _ in 0..1_000_000 {
core::hint::black_box(()); // Do nothing, but keep the loop
}
}
}
In the ch32v00x-hal sample, the waiting part is implemented as follows, which feels cleaner and easier to handle:
unsafe {
qingke::riscv::asm::delay(10000000);
}
Conclusion
In this post, I used HAL to improve the source code. I've also refined the build and execution process, setting up a foundation for efficient development.
Discussion