Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions bins/esp/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[target.xtensa-esp32s3-none-elf]
runner = "probe-rs run --chip=esp32s3 --preverify --always-print-stacktrace --no-location --catch-hardfault"

[env]

[build]
rustflags = [
"-C", "link-arg=-nostartfiles",
]

target = "xtensa-esp32s3-none-elf"

[unstable]
build-std = ["alloc", "core"]
22 changes: 22 additions & 0 deletions bins/esp/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# will have compiled files and executables
debug/
target/

# Editor configuration
.vscode/
.zed/
.helix/
.nvim.lua

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

# RustRover
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
72 changes: 72 additions & 0 deletions bins/esp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
[package]
edition = "2024"
name = "picocraft-esp32s3"
rust-version = "1.88"
version = "0.1.0"

[[bin]]
name = "esp32s3"
path = "./src/bin/esp32s3.rs"
test = false

[[test]]
harness = false
name = "hello_test"

[lib]
test = false

[dependencies]
esp-hal = { version = "1.0.0", features = ["esp32s3", "unstable"] }

esp-rtos = { version = "0.2.0", features = [
"embassy",
"esp-alloc",
"esp-radio",
"esp32s3",
] }

esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32s3"] }

embassy-net = { version = "0.8.0", features = [
"dhcpv4",
"medium-ethernet",
"tcp",
"udp",
] }
embedded-io = "0.7.1"
embedded-io-async = "0.7.0"
esp-alloc = "0.9.0"
rtt-target = "0.6.2"
# for more networking protocol support see https://crates.io/crates/edge-net
embassy-executor = { version = "0.9.1", features = [] }
embassy-time = "0.5.0"
esp-radio = { version = "0.17.0", features = [
"esp-alloc",
"esp32s3",
"smoltcp",
"unstable",
"wifi",
] }
smoltcp = { version = "0.12.0", default-features = false, features = [
"medium-ethernet",
"multicast",
"proto-dhcpv4",
"proto-dns",
"proto-ipv4",
"socket-dns",
"socket-icmp",
"socket-raw",
"socket-tcp",
"socket-udp",
] }

critical-section = "1.2.0"
static_cell = "2.1.1"

[dev-dependencies]
embedded-test = { version = "0.7.0", features = [
"embassy",
"external-executor",
"xtensa-semihosting",
] }
61 changes: 61 additions & 0 deletions bins/esp/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
fn main() {
linker_be_nice();
println!("cargo:rustc-link-arg-tests=-Tembedded-test.x");
// make sure linkall.x is the last linker script (otherwise might cause problems
// with flip-link)
println!("cargo:rustc-link-arg=-Tlinkall.x");
}

fn linker_be_nice() {
let args: Vec<String> = std::env::args().collect();
if args.len() > 1 {
let kind = &args[1];
let what = &args[2];

match kind.as_str() {
"undefined-symbol" => match what.as_str() {
"_defmt_timestamp" => {
eprintln!();
eprintln!(
"💡 `defmt` not found - make sure `defmt.x` is added as a linker script \
and you have included `use defmt_rtt as _;`"
);
eprintln!();
}
"_stack_start" => {
eprintln!();
eprintln!("💡 Is the linker script `linkall.x` missing?");
eprintln!();
}
"esp_rtos_initialized" | "esp_rtos_yield_task" | "esp_rtos_task_create" => {
eprintln!();
eprintln!(
"💡 `esp-radio` has no scheduler enabled. Make sure you have initialized \
`esp-rtos` or provided an external scheduler."
);
eprintln!();
}
"embedded_test_linker_file_not_added_to_rustflags" => {
eprintln!();
eprintln!(
"💡 `embedded-test` not found - make sure `embedded-test.x` is added as a \
linker script for tests"
);
eprintln!();
}
_ => (),
},
// we don't have anything helpful for "missing-lib" yet
_ => {
std::process::exit(1);
}
}

std::process::exit(0);
}

println!(
"cargo:rustc-link-arg=-Wl,--error-handling-script={}",
std::env::current_exe().unwrap().display()
);
}
2 changes: 2 additions & 0 deletions bins/esp/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[toolchain]
channel = "esp"
56 changes: 56 additions & 0 deletions bins/esp/src/bin/esp32s3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#![no_std]
#![no_main]
#![deny(
clippy::mem_forget,
reason = "mem::forget is generally not safe to do with esp_hal types, especially those \
holding buffers for the duration of a data transfer."
)]

use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};
use esp_hal::clock::CpuClock;
use esp_hal::timer::timg::TimerGroup;
use rtt_target::rprintln;

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}

extern crate alloc;

// This creates a default app-descriptor required by the esp-idf bootloader.
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!();

#[esp_rtos::main]
async fn main(spawner: Spawner) -> ! {
// generator version: 1.0.1

rtt_target::rtt_init_print!();

let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);

esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);

let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0);

rprintln!("Embassy initialized!");

let radio_init = esp_radio::init().expect("Failed to initialize Wi-Fi/BLE controller");
let (mut _wifi_controller, _interfaces) =
esp_radio::wifi::new(&radio_init, peripherals.WIFI, Default::default())
.expect("Failed to initialize Wi-Fi controller");

// TODO: Spawn some tasks
let _ = spawner;

loop {
rprintln!("Hello world!");
Timer::after(Duration::from_secs(1)).await;
}

// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0/examples/src/bin
}
1 change: 1 addition & 0 deletions bins/esp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#![no_std]
27 changes: 27 additions & 0 deletions bins/esp/tests/hello_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! Demo test suite using embedded-test
//!
//! You can run this using `cargo test` as usual.

#![no_std]
#![no_main]

esp_bootloader_esp_idf::esp_app_desc!();

#[cfg(test)]
#[embedded_test::tests(executor = esp_rtos::embassy::Executor::new())]
mod tests {

#[init]
fn init() {
let peripherals = esp_hal::init(esp_hal::Config::default());

let timg1 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG1);
esp_rtos::start(timg1.timer0);
}

#[test]
async fn hello_test() {
embassy_time::Timer::after(embassy_time::Duration::from_millis(100)).await;
assert_eq!(1 + 1, 2);
}
}
Loading