This commit is contained in:
Pat Nakajima 2026-06-11 22:04:17 -07:00
parent 3b5df990aa
commit 548636779e
4 changed files with 976 additions and 402 deletions

View File

@ -4,7 +4,7 @@ runner = "espflash flash --monitor -L defmt --no-skip --chip esp32c6"
rustflags = ["-C", "force-frame-pointers"] rustflags = ["-C", "force-frame-pointers"]
[env] [env]
DEFMT_LOG = "trace" DEFMT_LOG = "info"
[build] [build]
rustflags = [ rustflags = [

1218
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,7 @@ path = "./src/bin/main.rs"
[dependencies] [dependencies]
ssd1677 = { path = "../forks/SSD1677" } ssd1677 = { path = "../forks/SSD1677" }
defmt = "0.3.10" defmt = "1.0.1"
embassy-net = { version = "0.6.0", features = [ embassy-net = { version = "0.6.0", features = [
"dhcpv4", "dhcpv4",
"medium-ethernet", "medium-ethernet",
@ -18,8 +18,8 @@ embassy-net = { version = "0.6.0", features = [
] } ] }
embedded-io = "0.6.1" embedded-io = "0.6.1"
embedded-io-async = "0.6.1" embedded-io-async = "0.6.1"
esp-alloc = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102" } esp-alloc = "0.10.0"
esp-hal = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [ esp-hal = { version = "1.1.1", features = [
"defmt", "defmt",
"esp32c6", "esp32c6",
"unstable", "unstable",
@ -36,30 +36,23 @@ smoltcp = { version = "0.12.0", default-features = false, features = [
] } ] }
# for more networking protocol support see https://crates.io/crates/edge-net # for more networking protocol support see https://crates.io/crates/edge-net
critical-section = "1.2.0" critical-section = "1.2.0"
embassy-executor = { version = "0.7.0", features = ["defmt", "nightly"] } embassy-executor = { version = "0.10.0", features = ["defmt", "nightly"] }
embassy-time = { version = "0.4.0", features = ["generic-queue-8"] } embassy-time = { version = "0.5.0", features = ["generic-queue-8"] }
esp-hal-embassy = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [ esp-rtos = { version = "0.3.0", features = ["embassy", "defmt", "esp32c6"] }
"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 } heapless = { version = "0.8.0", default-features = false }
static_cell = { version = "2.1.0", features = ["nightly"] } static_cell = { version = "2.1.0", features = ["nightly"] }
embedded-hal = { version = "1.0.0", features = ["defmt-03"] } embedded-hal = { version = "1.0.0", features = ["defmt-03"] }
esp-println = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = [ esp-println = { version = "0.17.0", features = [
"defmt-espflash", "defmt-espflash",
"esp32c6", "esp32c6",
"log", "log-04",
] } ] }
esp-backtrace = { git = "https://github.com/esp-rs/esp-hal", rev = "4ec4e6cfbdc02f2fa92f85985f5d98fd6a22b102", features = ["exception-handler", "panic-handler", "esp32c6", "defmt"] } esp-backtrace = { version = "0.19.0", features = ["panic-handler", "esp32c6", "defmt"] }
esp-bootloader-esp-idf = { version = "0.5.0", features = ["esp32c6"] }
embedded-graphics = { version = "0.8.1", features = ["defmt"] } embedded-graphics = { version = "0.8.1", features = ["defmt"] }
embassy-futures = { version = "0.1.1", features = ["defmt"] } embassy-futures = { version = "0.1.1", features = ["defmt"] }
lm3630a = { version = "0.1.1", features = ["async"] }
[profile.dev] [profile.dev]
# Rust debug is too slow. # Rust debug is too slow.

View File

@ -13,17 +13,25 @@ use embedded_graphics::text::Text;
use embedded_hal::delay::DelayNs; use embedded_hal::delay::DelayNs;
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice}; use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
use esp_backtrace as _; use esp_backtrace as _;
use esp_hal::gpio::{Input, Level, Output}; use esp_hal::gpio::{Input, InputConfig, Level, Output, Pull};
use esp_hal::timer::systimer::SystemTimer; use esp_hal::i2c::master::{Config as I2cConfig, I2c};
use esp_hal::{clock::CpuClock, spi::master::Spi}; use esp_hal::interrupt::software::SoftwareInterruptControl;
use esp_hal::timer::timg::TimerGroup;
use esp_hal::{clock::CpuClock, spi::master::Spi, time::Rate};
use esp_hal::{spi, Blocking}; use esp_hal::{spi, Blocking};
use esp_println as _; use esp_println as _;
use lm3630a::{
Address, Bank, Brightness, Configuration, ControlConfig, FullScaleCurrent, Led2Bank, Lm3630a,
Mapping,
};
// use panic_rtt_target as _; // use panic_rtt_target as _;
use ssd1677::display::{Dimensions, DisplayUpdateMode, Rotation}; use ssd1677::display::{Dimensions, DisplayUpdateMode, Rotation};
use ssd1677::graphics::GraphicsDisplayBlackAndWhite; use ssd1677::graphics::GraphicsDisplayBlackAndWhite;
extern crate alloc; extern crate alloc;
esp_bootloader_esp_idf::esp_app_desc!();
struct SpiDriver { struct SpiDriver {
inner: Spi<'static, Blocking>, inner: Spi<'static, Blocking>,
delay: Delay, delay: Delay,
@ -54,20 +62,38 @@ impl SpiDevice for SpiDriver {
} }
} }
#[esp_hal_embassy::main] #[esp_rtos::main]
async fn main(spawner: Spawner) { async fn main(spawner: Spawner) {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config); let peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 48 * 1024); esp_alloc::heap_allocator!(size: 48 * 1024);
let timer0 = SystemTimer::new(peripherals.SYSTIMER); let software_interrupt = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_hal_embassy::init(timer0.alarm0); let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0, software_interrupt.software_interrupt0);
info!("Embassy initialized!"); info!("Embassy initialized!");
let _ = spawner; let _ = spawner;
let button_bottom = Input::new(
peripherals.GPIO14,
InputConfig::default().with_pull(Pull::Up),
);
let button_left = Input::new(
peripherals.GPIO19,
InputConfig::default().with_pull(Pull::Up),
);
let button_right_up = Input::new(
peripherals.GPIO20,
InputConfig::default().with_pull(Pull::Up),
);
let button_right_down = Input::new(
peripherals.GPIO21,
InputConfig::default().with_pull(Pull::Up),
);
let spi_config = spi::master::Config::default().with_mode(spi::Mode::_0); let spi_config = spi::master::Config::default().with_mode(spi::Mode::_0);
let spi = Spi::new(peripherals.SPI2, spi_config) let spi = Spi::new(peripherals.SPI2, spi_config)
.expect("did not get SPI") .expect("did not get SPI")
@ -115,6 +141,95 @@ async fn main(spawner: Spawner) {
.expect("did not clear screen"); .expect("did not clear screen");
screen.update(DisplayUpdateMode::Slow).unwrap(); screen.update(DisplayUpdateMode::Slow).unwrap();
let mut backlight_enable = Output::new(peripherals.GPIO18, Level::High, Default::default());
backlight_enable.set_high();
Timer::after_millis(10).await;
let mut i2c = I2c::new(
peripherals.I2C0,
I2cConfig::default().with_frequency(Rate::from_khz(10)),
)
.expect("did not get I2C")
.with_sda(peripherals.GPIO22)
.with_scl(peripherals.GPIO23);
info!("Scanning I2C bus");
let mut devices_found = 0u8;
for address in 0x08..=0x77 {
if i2c.write(address, &[]).is_ok() {
devices_found += 1;
info!("I2C device ACK at {}", address);
}
}
info!("I2C scan complete, found {} devices", devices_found);
let mut backlight = Lm3630a::new(i2c, Address::SelLow);
backlight.wait_until_ready(&mut Delay);
let current = FullScaleCurrent::from_code(6).expect("invalid backlight current code");
let backlight_init: Result<(), esp_hal::i2c::master::Error> = (|| {
let revision = backlight.revision().map_err(|error| {
defmt::error!("LM3630A did not respond at 0x36: {:?}", error);
error
})?;
info!("LM3630A revision {}", revision);
backlight
.set_configuration(Configuration::default())
.map_err(|error| {
defmt::error!("LM3630A configuration write failed: {:?}", error);
error
})?;
backlight
.set_full_scale_current(Bank::A, current)
.map_err(|error| {
defmt::error!("LM3630A bank A current write failed: {:?}", error);
error
})?;
backlight
.set_full_scale_current(Bank::B, current)
.map_err(|error| {
defmt::error!("LM3630A bank B current write failed: {:?}", error);
error
})?;
backlight
.set_brightness(Bank::A, Brightness::from_raw(128))
.map_err(|error| {
defmt::error!("LM3630A bank A brightness write failed: {:?}", error);
error
})?;
backlight
.set_brightness(Bank::B, Brightness::from_raw(128))
.map_err(|error| {
defmt::error!("LM3630A bank B brightness write failed: {:?}", error);
error
})?;
backlight
.set_control(ControlConfig {
sleep: false,
bank_a_mapping: Mapping::Linear,
bank_b_mapping: Mapping::Linear,
bank_a_enabled: true,
bank_b_enabled: true,
led2_bank: Led2Bank::B,
})
.map_err(|error| {
defmt::error!("LM3630A control write failed: {:?}", error);
error
})?;
Ok(())
})();
if backlight_init.is_ok() {
info!("LM3630A backlight enabled");
if let Err(error) = backlight.set_brightness(Bank::A, Brightness::from_raw(100)) {
defmt::error!("LM3630A brightness update failed: {:?}", error);
}
} else {
defmt::error!("Skipping LM3630A brightness update because init failed");
}
loop { loop {
info!("Turning {}", if is_on { "on" } else { "off" }); info!("Turning {}", if is_on { "on" } else { "off" });
@ -136,7 +251,7 @@ async fn main(spawner: Spawner) {
.background_color(BinaryColor::Off) .background_color(BinaryColor::Off)
.build(); .build();
Text::new(text, Point::new(16, 24), style) Text::new(text, Point::new(16, 28), style)
.draw(&mut screen) .draw(&mut screen)
.expect("did not draw text"); .expect("did not draw text");