OLED driver with shared SPI bus integrated

This commit was merged in pull request #35.
This commit is contained in:
2026-08-22 22:46:09 +02:00
committed by ede1998
parent 71db893551
commit 9cd595acfe
19 changed files with 312 additions and 123 deletions
+41 -10
View File
@@ -10,7 +10,7 @@
use alloc::boxed::Box;
use creaturedex::card::decoder::split_nfc_hex;
use creaturedex::card::model::Card;
use creaturedex::display::primary_lcd::{PrimaryLcdDisplay, init_primary_lcd};
use creaturedex::display::shared_bus::{DualSecondaryDisplay, init_dual_displays};
use creaturedex::display::tertiary_lcd::{init_tertiary_lcd, write_wrapped};
use creaturedex::drivers::nfc_pn532::NfcPn532Driver;
use creaturedex::navigation::inputs::Inputs;
@@ -18,13 +18,19 @@ use creaturedex::navigation::navigation::{self, CARD_DATA};
use creaturedex::network::wifi::setup_wifi;
use embassy_executor::Spawner;
use embassy_time::Instant;
use embedded_graphics::pixelcolor::BinaryColor;
use embedded_graphics::{
mono_font::{MonoTextStyle, ascii::FONT_6X10},
prelude::*,
text::Text,
};
use embedded_hal_bus::i2c::AtomicDevice;
use embedded_hal_bus::util::AtomicCell;
use esp_hal::Blocking;
use esp_hal::clock::CpuClock;
use esp_hal::gpio::{Input, InputConfig, Pull};
use esp_hal::timer::timg::TimerGroup;
use esp_hal::i2c::master::{Config as I2cConfig, I2c};
use esp_hal::timer::timg::TimerGroup;
use log::error;
#[panic_handler]
@@ -59,19 +65,22 @@ async fn main(spawner: Spawner) {
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let display: &mut PrimaryLcdDisplay = Box::leak(Box::new(init_primary_lcd(
let (display, oled) = Box::leak(Box::new(init_dual_displays(
peripherals.SPI2,
peripherals.GPIO36, // sck
peripherals.GPIO35, // mosi
peripherals.GPIO37, // miso
peripherals.GPIO11, // primary cs
peripherals.GPIO13, // oled cs
peripherals.GPIO10, // shared reset
peripherals.GPIO12, // shared dc
)));
let config = I2cConfig::default().with_frequency(esp_hal::time::Rate::from_khz(400));
let i2c = match I2c::new(peripherals.I2C0, config) {
Ok(bus) => bus.with_sda(peripherals.GPIO17).with_scl(peripherals.GPIO18),
Ok(bus) => bus
.with_sda(peripherals.GPIO17)
.with_scl(peripherals.GPIO18),
Err(e) => {
log::error!("Shared I2C bus initialization failed for GPIO17/GPIO18: {e:?}");
panic!("Shared I2C bus initialization failed");
@@ -82,10 +91,12 @@ async fn main(spawner: Spawner) {
let mut lcd = init_tertiary_lcd(AtomicDevice::new(shared_i2c));
if let Err(_) = write_wrapped(&mut lcd, "Testing more than 16 chars what happens now?") {
log::error!("Tertiary LCD startup text write failed over shared I2C bus; check the shared bus, wiring, and device responses");
log::error!(
"Tertiary LCD startup text write failed over shared I2C bus; check the shared bus, wiring, and device responses"
);
}
// setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
let mut nfc_driver = NfcPn532Driver::new(AtomicDevice::new(shared_i2c));
if nfc_driver.configure_sam().await.is_ok() {
@@ -104,14 +115,17 @@ async fn main(spawner: Spawner) {
ok: Input::new(peripherals.GPIO0, button_config),
};
display_shit(oled);
log::info!("Setup complete, entering main loop");
spawner.spawn(navigation::run(inputs, display).expect("run task failed"));
spawner.spawn(nfc_driver_task(nfc_driver).expect("nfc driver task failed"));
}
#[embassy_executor::task]
async fn nfc_driver_task(mut nfc_driver: NfcPn532Driver<AtomicDevice<'static, I2c<'static, Blocking>>>) {
async fn nfc_driver_task(
mut nfc_driver: NfcPn532Driver<AtomicDevice<'static, I2c<'static, Blocking>>>,
) {
loop {
while CARD_DATA.lock().await.is_none() {
let start = Instant::now();
@@ -121,9 +135,16 @@ async fn nfc_driver_task(mut nfc_driver: NfcPn532Driver<AtomicDevice<'static, I2
log::error!("Failed to split NFC card data");
continue;
};
CARD_DATA.lock().await.replace(Card::try_from(split_data).unwrap());
CARD_DATA
.lock()
.await
.replace(Card::try_from(split_data).unwrap());
let elapsed_ms = start.elapsed().as_millis();
log::info!("NFC read duration: {} ms, card data length: {}", elapsed_ms, card_data.len());
log::info!(
"NFC read duration: {} ms, card data length: {}",
elapsed_ms,
card_data.len()
);
}
Err(_) => {
log::info!("No NFC card found");
@@ -133,3 +154,13 @@ async fn nfc_driver_task(mut nfc_driver: NfcPn532Driver<AtomicDevice<'static, I2
embassy_time::Timer::after(embassy_time::Duration::from_millis(1000)).await;
}
}
fn display_shit(oled: &mut DualSecondaryDisplay<'static>) {
oled.clear().unwrap();
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Text::new("Hello OLED", Point::new(10, 20), text_style)
.draw(oled)
.unwrap();
oled.flush().unwrap();
}