feat: init esp32 project

This commit is contained in:
Jet Pham 2025-10-01 12:41:49 -07:00
parent 3f542d8db0
commit a69b064f39
No known key found for this signature in database
15 changed files with 1804 additions and 10 deletions

17
.cargo/config.toml Normal file
View file

@ -0,0 +1,17 @@
[target.riscv32imac-unknown-none-elf]
runner = "probe-rs run --chip=esp32c6 --preverify --always-print-stacktrace --no-location --catch-hardfault"
[env]
DEFMT_LOG="info"
[build]
rustflags = [
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
# NOTE: May negatively impact performance of produced code
"-C", "force-frame-pointers",
]
target = "riscv32imac-unknown-none-elf"
[unstable]
build-std = ["alloc", "core"]

20
.gitignore vendored
View file

@ -1 +1,19 @@
/target # will have compiled files and executables
debug/
target/
.vscode/
.zed/
.helix/
# 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/

1478
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,60 @@
[package] [package]
name = "Firebeetle_2_Board_ESP32-C6" edition = "2021"
version = "0.1.0" name = "firebeetle_2_board_esp32_c6"
edition = "2024" rust-version = "1.86"
version = "0.1.0"
[[bin]]
name = "firebeetle_2_board_esp32_c6"
path = "./src/bin/main.rs"
[dependencies] [dependencies]
defmt = "1.0.1"
esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32c6"] }
esp-hal = { version = "=1.0.0-rc.0", features = [
"defmt",
"esp32c6",
"unstable",
] }
critical-section = "1.2.0"
embedded-io = { version = "0.6.1", features = ["defmt-03"] }
esp-alloc = { version = "0.8.0", features = ["defmt"] }
esp-wifi = { version = "0.15.0", features = [
"builtin-scheduler",
"defmt",
"esp-alloc",
"esp32c6",
"smoltcp",
"wifi",
] }
panic-rtt-target = { version = "0.2.0", features = ["defmt"] }
rtt-target = { version = "0.6.1", features = ["defmt"] }
smoltcp = { version = "0.12.0", default-features = false, features = [
"defmt",
"medium-ethernet",
"multicast",
"proto-dhcpv4",
"proto-dns",
"proto-ipv4",
"socket-dns",
"socket-icmp",
"socket-raw",
"socket-tcp",
"socket-udp",
] }
[profile.dev]
# Rust debug is too slow.
# For debug builds always builds with some optimization
opt-level = "s"
[profile.release]
codegen-units = 1 # LLVM can perform better optimizations using a single thread
debug = 2
debug-assertions = false
incremental = false
lto = 'fat'
opt-level = 's'
overflow-checks = false

View file

@ -9,19 +9,19 @@ On September 28, 2025, [DFRobot](https://www.dfrobot.com/?srsltid=AfmBOoqllNjgG_
They very generously donated 90 pcs [esp32 C6](https://wiki.dfrobot.com/SKU_DFR1075_FireBeetle_2_Board_ESP32_C6)/ several [esp32 C5](https://wiki.dfrobot.com/SKU_DFR1222_Firebeetle_2_ESP32_C5_Development_Board)/ several [4 Channel USB to Serial Converter (RS485 / RS232 / TTL)](https://www.dfrobot.com/product-2879.html) They very generously donated 90 pcs [esp32 C6](https://wiki.dfrobot.com/SKU_DFR1075_FireBeetle_2_Board_ESP32_C6)/ several [esp32 C5](https://wiki.dfrobot.com/SKU_DFR1222_Firebeetle_2_ESP32_C5_Development_Board)/ several [4 Channel USB to Serial Converter (RS485 / RS232 / TTL)](https://www.dfrobot.com/product-2879.html)
<p align="center"> <p align="center">
<img src="boards.jpg" alt="Firebeetle 2 Board ESP32-C6 Boards" width="500" /> <img src="assets/boards.jpg" alt="Firebeetle 2 Board ESP32-C6 Boards" width="500" />
</p> </p>
Thank you very much to DFRobot <3 Thank you very much to DFRobot <3
<p align="center"> <p align="center">
<img src="grouppic.jpg" alt="A group picture including a DFRobot representative who was very lovely" width="500" /> <img src="assets/grouppic.jpg" alt="A group picture including a DFRobot representative who was very lovely" width="500" />
</p> </p>
On September 30, 2025, a few Noisebridgers got together and started to hack on them. [Jet](https://jetpham.com) brought up programming them with [embedded rust](https://docs.rust-embedded.org/book/). This repo is our attempt to work on them together. To commemorate we took this picture: On September 30, 2025, a few Noisebridgers got together and started to hack on them. [Jet](https://jetpham.com) brought up programming them with [embedded rust](https://docs.rust-embedded.org/book/). This repo is our attempt to work on them together. To commemorate we took this picture:
<p align="center"> <p align="center">
<img src="icon.jpg" alt="A group picture of Noisebridgers holding alchohol" width="500" /> <img src="assets/icon.jpg" alt="A group picture of Noisebridgers holding alchohol" width="500" />
</p> </p>
> We used Kirkland Vodka to clean flux after soldering header pins > We used Kirkland Vodka to clean flux after soldering header pins

View file

Before

Width:  |  Height:  |  Size: 446 KiB

After

Width:  |  Height:  |  Size: 446 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 526 KiB

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 384 KiB

After

Width:  |  Height:  |  Size: 384 KiB

Before After
Before After

53
build.rs Normal file
View file

@ -0,0 +1,53 @@
fn main() {
linker_be_nice();
println!("cargo:rustc-link-arg=-Tdefmt.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_wifi_preempt_enable"
| "esp_wifi_preempt_yield_task"
| "esp_wifi_preempt_task_create" => {
eprintln!();
eprintln!("💡 `esp-wifi` has no scheduler enabled. Make sure you have the `builtin-scheduler` feature enabled, or that you provide 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=--error-handling-script={}",
std::env::current_exe().unwrap().display()
);
}

96
flake.lock generated Normal file
View file

@ -0,0 +1,96 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1759036355,
"narHash": "sha256-0m27AKv6ka+q270dw48KflE0LwQYrO7Fm4/2//KCVWg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e9f00bd893984bc8ce46c895c3bf7cac95331127",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1744536153,
"narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": "nixpkgs_2"
},
"locked": {
"lastModified": 1759372351,
"narHash": "sha256-kULiC2oMMuyaO92gPiu+6XBfeXuFcXaauwo0tXAwXdQ=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "7ef14552303de7128662666f9a71342099ffc725",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

33
flake.nix Normal file
View file

@ -0,0 +1,33 @@
{
description = "A devShell example";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, rust-overlay, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem (system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs {
inherit system overlays;
};
in
{
devShells.default = with pkgs; mkShell {
buildInputs = [
(rust-bin.selectLatestNightlyWith (toolchain: toolchain.default.override {
targets = [ "riscv32imac-unknown-none-elf" ];
extensions = [ "rust-src" "rustfmt" "clippy" "rust-analyzer" ];
}))
espflash
esp-generate
probe-rs
];
};
}
);
}

4
rust-toolchain.toml Normal file
View file

@ -0,0 +1,4 @@
[toolchain]
channel = "nightly"
components = ["rust-src"]
targets = ["riscv32imac-unknown-none-elf"]

43
src/bin/main.rs Normal file
View file

@ -0,0 +1,43 @@
#![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 defmt::info;
use esp_hal::clock::CpuClock;
use esp_hal::main;
use esp_hal::time::{Duration, Instant};
use esp_hal::timer::timg::TimerGroup;
use panic_rtt_target as _;
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!();
#[main]
fn main() -> ! {
// generator version: 0.5.0
rtt_target::rtt_init_defmt!();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 64 * 1024);
let timg0 = TimerGroup::new(peripherals.TIMG0);
let _init = esp_wifi::init(timg0.timer0, esp_hal::rng::Rng::new(peripherals.RNG)).unwrap();
loop {
info!("Hello world!");
let delay_start = Instant::now();
while delay_start.elapsed() < Duration::from_millis(500) {}
}
// for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0-rc.0/examples/src/bin
}

1
src/lib.rs Normal file
View file

@ -0,0 +1 @@
#![no_std]

View file

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}