Tree @main (Download .tar.gz)
t144-meshcore-example
A rust-based Meshcore firmware proof-of-concept for the Heltek T114 using Meshcore-rs and Embassy.
Notes
I don't have the standard ST7789 TFT display module Heltek ships with these, so the code is written for the SSD1322 OLED I do have. If you have the dev boad with display, I'd appreciate a patch that changes to that since that's a much more common configuration.
The code layout is a little overengineered since I adapted this from a larger project that uses multiple crates to support different boards (with different architectures).
Because of this lib.rs contains the firmware's "logic" as different embassy tasks, while src/bin contains the code specific to the Heltek T114 board.
The tasks defined in lib.rs aren't decorated with embassy's #[embassy_executor::task] as you might expect:
since the arguments to the tasks (the peripherals the tasks operate on) vary from platform to platform, the task functions have to be generic.
They are specialized in the modules in src/bin/example and started from src/bin/example/main.rs:
// generic task definition (uses "impl Task") - can't be turned into an embassy task
pub async fn led_task(
led_pin: &Mutex<CriticalSectionRawMutex, impl StatefulOutputPin<Error = Infallible>>,
) {
// ...
}
// specialized task definition
#[embassy_executor::task]
async fn led_task(led_pin: &'static PinMutex<'static>) {
t114_meshcore_example::led_task(led_pin).await;
}
// embassy entrypoint
#[embassy_executor::main]
async fn main(spawner: Spawner) {
// ...
let p = embassy_nrf::init(Default::default());
// start task
let led = Output::new(p.P1_03, Level::High, OutputDrive::Standard);
let pin: PinMutex = Mutex::new(led);
let pin_ref = Box::leak(Box::new(pin));
spawner.spawn(led_task(pin_ref)).unwrap();
}
Building
You can run and debug using probe-rs:
# install probe-rs
$ DEFMT_LOG=info cargo run
Or just build the ELF file and deploy it using some other method:
$ cargo build
$ some-flashing-tool target/thumbv7em-none-eabi/debug/main