This commit is contained in:
Pat Nakajima 2025-07-03 10:55:52 -07:00
commit 3b5df990aa
14 changed files with 2050 additions and 0 deletions

20
.cargo/config.toml Normal file
View File

@ -0,0 +1,20 @@
[target.riscv32imac-unknown-none-elf]
# runner = "probe-rs run --chip=esp32c6 --always-print-stacktrace --no-location --catch-hardfault"
runner = "espflash flash --monitor -L defmt --no-skip --chip esp32c6"
rustflags = ["-C", "force-frame-pointers"]
[env]
DEFMT_LOG = "trace"
[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"]

17
.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# 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/

7
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
"recommendations": [
"rust-lang.rust-analyzer",
"tamasfe.even-better-toml",
"fill-labs.dependi"
]
}

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"rust-analyzer.cargo.allTargets": false,
"rust-analyzer.cargo.target": "riscv32imac-unknown-none-elf",
}

1562
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

76
Cargo.toml Normal file
View File

@ -0,0 +1,76 @@
[package]
edition = "2021"
name = "kinda"
version = "0.1.0"
[[bin]]
name = "kinda"
path = "./src/bin/main.rs"
[dependencies]
ssd1677 = { path = "../forks/SSD1677" }
defmt = "0.3.10"
embassy-net = { version = "0.6.0", features = [
"dhcpv4",
"medium-ethernet",
"tcp",
"udp",
] }
embedded-io = "0.6.1"
embedded-io-async = "0.6.1"
esp-alloc = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102" }
esp-hal = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [
"defmt",
"esp32c6",
"unstable",
] }
smoltcp = { version = "0.12.0", default-features = false, features = [
"proto-dhcpv4",
"proto-dns",
"proto-ipv4",
"socket-dns",
"socket-icmp",
"socket-raw",
"socket-tcp",
"socket-udp",
] }
# for more networking protocol support see https://crates.io/crates/edge-net
critical-section = "1.2.0"
embassy-executor = { version = "0.7.0", features = ["defmt", "nightly"] }
embassy-time = { version = "0.4.0", features = ["generic-queue-8"] }
esp-hal-embassy = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [
"esp32c6",
] }
esp-wifi = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [
"builtin-scheduler",
"defmt",
"esp-alloc",
"esp32c6",
"wifi",
] }
heapless = { version = "0.8.0", default-features = false }
static_cell = { version = "2.1.0", features = ["nightly"] }
embedded-hal = { version = "1.0.0", features = ["defmt-03"] }
esp-println = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [
"defmt-espflash",
"esp32c6",
"log",
] }
esp-backtrace = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = ["exception-handler", "panic-handler", "esp32c6", "defmt"] }
embedded-graphics = { version = "0.8.1", features = ["defmt"] }
embassy-futures = { version = "0.1.1", features = ["defmt"] }
[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

18
Embed.toml Normal file
View File

@ -0,0 +1,18 @@
[default.probe]
protocol = "Jtag"
# The speed in kHz of the data link to the target.
speed = 1337
[default.general]
chip = "esp32c6"
connect_under_reset = true
[default.rtt]
enabled = true
timeout = 3000
log_enabled = false
log_path = "./logs"
[default.gdb]
enabled = true
gdb_connection_string = "127.0.0.1:9998"

BIN
GDEQ0426T82.pdf Normal file

Binary file not shown.

BIN
SSD1677.pdf Normal file

Binary file not shown.

41
build.rs Normal file
View File

@ -0,0 +1,41 @@
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!();
}
_ => (),
},
// 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()
);
}

4
rust-toolchain.toml Normal file
View File

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

151
src/bin/main.rs Normal file
View File

@ -0,0 +1,151 @@
#![no_std]
#![no_main]
#![feature(impl_trait_in_assoc_type)]
use defmt::info;
use embassy_executor::Spawner;
use embassy_time::{Delay, Timer};
use embedded_graphics::mono_font::ascii::FONT_10X20;
use embedded_graphics::mono_font::MonoTextStyleBuilder;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::prelude::Point;
use embedded_graphics::text::Text;
use embedded_hal::delay::DelayNs;
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
use esp_backtrace as _;
use esp_hal::gpio::{Input, Level, Output};
use esp_hal::timer::systimer::SystemTimer;
use esp_hal::{clock::CpuClock, spi::master::Spi};
use esp_hal::{spi, Blocking};
use esp_println as _;
// use panic_rtt_target as _;
use ssd1677::display::{Dimensions, DisplayUpdateMode, Rotation};
use ssd1677::graphics::GraphicsDisplayBlackAndWhite;
extern crate alloc;
struct SpiDriver {
inner: Spi<'static, Blocking>,
delay: Delay,
}
impl ErrorType for SpiDriver {
type Error = spi::Error;
}
impl SpiDevice for SpiDriver {
fn transaction(
&mut self,
operations: &mut [embedded_hal::spi::Operation<'_, u8>],
) -> Result<(), Self::Error> {
for op in operations {
match op {
Operation::DelayNs(delay) => self.delay.delay_ns(*delay),
Operation::Read(words) => self.inner.read(words)?,
Operation::Transfer(_in_bytes, _out_bytes) => {
todo!()
}
Operation::TransferInPlace(words) => self.inner.transfer_in_place(words)?,
Operation::Write(words) => self.inner.write(words)?,
}
}
Ok(())
}
}
#[esp_hal_embassy::main]
async fn main(spawner: Spawner) {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 48 * 1024);
let timer0 = SystemTimer::new(peripherals.SYSTIMER);
esp_hal_embassy::init(timer0.alarm0);
info!("Embassy initialized!");
let _ = spawner;
let spi_config = spi::master::Config::default().with_mode(spi::Mode::_0);
let spi = Spi::new(peripherals.SPI2, spi_config)
.expect("did not get SPI")
.with_cs(peripherals.GPIO2)
.with_sck(peripherals.GPIO6)
.with_mosi(peripherals.GPIO7);
let spi_driver = SpiDriver {
inner: spi,
delay: Delay,
};
info!("Init controller");
let config = ssd1677::config::Builder::new()
.auto_update(false)
.dimensions(Dimensions {
rows: 480,
cols: 800,
})
.rotation(Rotation::Rotate270)
.build();
let interface = ssd1677::interface::Interface4Pin::new(
spi_driver,
Output::new(peripherals.GPIO3, Level::High, Default::default()),
Output::new(peripherals.GPIO4, Level::High, Default::default()),
Input::new(peripherals.GPIO5, Default::default()),
);
let mut display = ssd1677::display::Display::new(interface, config.unwrap());
Timer::after_millis(10).await;
info!("Reset display");
display.reset(&mut Delay).expect("failed to reset");
info!("Init display");
Timer::after_millis(10).await;
display.init().expect("failed to init");
let mut buf: [u8; 800 * 480 / 8] = [0; (800 * 480) / 8];
let mut screen = GraphicsDisplayBlackAndWhite::new(display, &mut buf);
let mut is_on = true;
screen
.clear(BinaryColor::Off)
.expect("did not clear screen");
screen.update(DisplayUpdateMode::Slow).unwrap();
loop {
info!("Turning {}", if is_on { "on" } else { "off" });
use embedded_graphics::Drawable;
let text = if is_on {
"does it work?"
} else {
"hell yea it works "
};
screen
.clear(BinaryColor::Off)
.expect("did not clear screen");
let style = MonoTextStyleBuilder::new()
.font(&FONT_10X20)
.text_color(BinaryColor::On)
.background_color(BinaryColor::Off)
.build();
Text::new(text, Point::new(16, 24), style)
.draw(&mut screen)
.expect("did not draw text");
screen
.update(ssd1677::display::DisplayUpdateMode::Fast)
.expect("did not update screen");
Timer::after_secs(3).await;
is_on = !is_on;
}
}

1
src/lib.rs Normal file
View File

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

149
template.yaml Normal file
View File

@ -0,0 +1,149 @@
options:
- !Option
name: unstable-hal
display_name: Enable unstable HAL features.
help: "This configuration enables unstable esp-hal features.
These come with no stability guarantees, and could be changed or removed at any time."
- !Option
name: alloc
display_name: Enable allocations via the esp-alloc crate.
help: esp-alloc comes with no stability guarantees at this time.
- !Option
name: wifi
display_name: Enable Wi-Fi via the esp-wifi crate.
help: esp-wifi comes with no stability guarantees at this time.
requires:
- alloc
- unstable-hal
chips:
- esp32
- esp32c2
- esp32c3
- esp32c6
- esp32s2
- esp32s3
- !Option
name: ble
display_name: Enable BLE via the esp-wifi crate.
help: esp-wifi comes with no stability guarantees at this time.
requires:
- alloc
- unstable-hal
chips:
- esp32
- esp32c2
- esp32c3
- esp32c6
- esp32h2
- esp32s3
- !Option
name: embassy
display_name: Add embassy framework support.
help: esp-hal-embassy comes with no stability guarantees at this time.
requires:
- unstable-hal
- !Option
name: probe-rs
display_name: Use probe-rs to flash and monitor instead of espflash.
help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and
monitor, and it can also be used to interactively debug an application, or run tests on the
hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs.
chips:
- esp32c6
- esp32h2
- esp32s3
- !Option
name: probe-rs
display_name: Use probe-rs to flash and monitor instead of espflash.
help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and
monitor, and it can also be used to interactively debug an application, or run tests on the
hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs.
probe-rs requires a debug probe like esp-prog, and will not work with USB-UART adapters that
often come on development boards.
chips:
- esp32
- esp32s2
- esp32c2
- esp32c3
- !Category
name: flashing-probe-rs
display_name: Flashing, logging and debugging (probe-rs)
requires:
- probe-rs
options:
- !Option
name: defmt
display_name: Use defmt to print messages.
selection_group: log-frontend
- !Option
name: panic-rtt-target
display_name: Use panic-rtt-target as the panic handler.
selection_group: panic-handler
requires:
- probe-rs
- !Category
name: flashing-espflash
display_name: Flashing, logging and debugging (espflash)
requires:
- "!probe-rs"
options:
- !Option
name: log
display_name: Use the log crate to print messages.
selection_group: log-frontend
requires:
- "!probe-rs"
- !Option
name: defmt
display_name: Use defmt to print messages.
selection_group: log-frontend
- !Option
name: esp-backtrace
display_name: Use esp-backtrace as the panic handler.
selection_group: panic-handler
requires:
- "!probe-rs"
- !Category
name: optional
display_name: Options
options:
- !Option
name: wokwi
display_name: Add support for Wokwi simulation using VS Code Wokwi extension.
chips:
- esp32
- esp32c3
- esp32c6
- esp32h2
- esp32s2
- esp32s3
- !Option
name: dev-container
display_name: Add support for VS Code Dev Containers and GitHub Codespaces.
- !Option
name: ci
display_name: Add GitHub Actions support with some basic checks.
- !Category
name: editor
display_name: Optional editor config files for rust-analyzer
options:
- !Option
name: helix
display_name: Add rust-analyzer settings for Helix Editor
- !Option
name: vscode
display_name: Add rust-analyzer settings for Visual Studio Code