WIP: Rust oled display #27
Generated
+91
@@ -322,6 +322,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"ndef",
|
"ndef",
|
||||||
"pn532",
|
"pn532",
|
||||||
|
"ssd1306",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -606,6 +607,17 @@ version = "0.5.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ba2aab1ef3793e6f7804162debb5ac5edb93b3d650fbcc5aeb72fcd0e6c03a0"
|
checksum = "7ba2aab1ef3793e6f7804162debb5ac5edb93b3d650fbcc5aeb72fcd0e6c03a0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "display-interface-i2c"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d964fa85bbbb5a6ecd06e58699407ac5dc3e3ad72dac0ab7e6b0d00a1cd262d"
|
||||||
|
dependencies = [
|
||||||
|
"display-interface",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"embedded-hal-async",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "display-interface-spi"
|
name = "display-interface-spi"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -1916,6 +1928,30 @@ version = "0.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "manyhow"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
|
||||||
|
dependencies = [
|
||||||
|
"manyhow-macros",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"syn 2.0.119",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "manyhow-macros"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-utils",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@@ -1931,6 +1967,19 @@ version = "0.1.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "maybe-async-cfg"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627"
|
||||||
|
dependencies = [
|
||||||
|
"manyhow",
|
||||||
|
"proc-macro2",
|
||||||
|
"pulldown-cmark",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.8.3"
|
version = "2.8.3"
|
||||||
@@ -2690,6 +2739,17 @@ dependencies = [
|
|||||||
"toml_edit",
|
"toml_edit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-utils"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.107"
|
version = "1.0.107"
|
||||||
@@ -2719,6 +2779,17 @@ dependencies = [
|
|||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pulldown-cmark"
|
||||||
|
version = "0.11.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.13.1",
|
||||||
|
"memchr",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.47"
|
version = "1.0.47"
|
||||||
@@ -3133,6 +3204,20 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a0f368519fc6c85fc1afdb769fb5a51123f6158013e143656e25a3485a0d401c"
|
checksum = "a0f368519fc6c85fc1afdb769fb5a51123f6158013e143656e25a3485a0d401c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ssd1306"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ed51935bdc6e9e976d3d9a747e768589eaea0cf26f483213bfededc947c8624"
|
||||||
|
dependencies = [
|
||||||
|
"display-interface",
|
||||||
|
"display-interface-i2c",
|
||||||
|
"display-interface-spi",
|
||||||
|
"embedded-graphics-core",
|
||||||
|
"embedded-hal 1.0.0",
|
||||||
|
"maybe-async-cfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stable_deref_trait"
|
name = "stable_deref_trait"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
@@ -3400,6 +3485,12 @@ version = "0.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-id-start"
|
name = "unicode-id-start"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ esp-hal-wifimanager = { git = "https://github.com/InvisibleUSA/esp-hal-wifimanag
|
|||||||
esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] }
|
esp-println = { version = "0.17.0", features = ["esp32s3", "log-04"] }
|
||||||
display-interface-spi = "0.5.0"
|
display-interface-spi = "0.5.0"
|
||||||
ili9341 = "0.6.0"
|
ili9341 = "0.6.0"
|
||||||
|
ssd1306 = "0.9.0"
|
||||||
embedded-hal = "1.0.0"
|
embedded-hal = "1.0.0"
|
||||||
embedded-hal-bus = "0.3.0"
|
embedded-hal-bus = "0.3.0"
|
||||||
embedded-graphics = "0.8.2"
|
embedded-graphics = "0.8.2"
|
||||||
|
|||||||
+29
-11
@@ -8,7 +8,9 @@
|
|||||||
#![deny(clippy::large_stack_frames)]
|
#![deny(clippy::large_stack_frames)]
|
||||||
|
|
||||||
use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2};
|
use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2};
|
||||||
use creaturedex::display::primary_lcd::init_primary_lcd;
|
use creaturedex::display::shared_bus::init_dual_displays;
|
||||||
|
|
||||||
|
|
||||||
use creaturedex::display::views::card_view::render_nfc_payload;
|
use creaturedex::display::views::card_view::render_nfc_payload;
|
||||||
use creaturedex::drivers::nfc_pn532::NfcPn532Driver;
|
use creaturedex::drivers::nfc_pn532::NfcPn532Driver;
|
||||||
use creaturedex::navigation::input::init_navigation_button;
|
use creaturedex::navigation::input::init_navigation_button;
|
||||||
@@ -16,8 +18,13 @@ use creaturedex::navigation::state::NavigationState;
|
|||||||
use creaturedex::network::wifi::setup_wifi;
|
use creaturedex::network::wifi::setup_wifi;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
|
use embedded_graphics::{
|
||||||
|
mono_font::{ascii::FONT_6X10, MonoTextStyle},
|
||||||
|
prelude::*,
|
||||||
|
text::Text,
|
||||||
|
};
|
||||||
use embedded_graphics::draw_target::DrawTarget;
|
use embedded_graphics::draw_target::DrawTarget;
|
||||||
use embedded_graphics::pixelcolor::Rgb565;
|
use embedded_graphics::pixelcolor::{BinaryColor, Rgb565};
|
||||||
use embedded_graphics::prelude::RgbColor;
|
use embedded_graphics::prelude::RgbColor;
|
||||||
use esp_hal::time::Duration;
|
use esp_hal::time::Duration;
|
||||||
use esp_hal::clock::CpuClock;
|
use esp_hal::clock::CpuClock;
|
||||||
@@ -68,23 +75,32 @@ async fn main(spawner: Spawner) {
|
|||||||
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
|
||||||
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
|
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
|
||||||
|
|
||||||
let mut display = init_primary_lcd(
|
let (mut display, mut oled) = init_dual_displays(
|
||||||
peripherals.SPI2,
|
peripherals.SPI2,
|
||||||
peripherals.GPIO36,
|
peripherals.GPIO36, // sck
|
||||||
peripherals.GPIO35,
|
peripherals.GPIO35, // mosi
|
||||||
peripherals.GPIO37,
|
peripherals.GPIO37, // miso
|
||||||
peripherals.GPIO11,
|
peripherals.GPIO11, // primary cs
|
||||||
peripherals.GPIO10,
|
peripherals.GPIO5, // oled cs
|
||||||
peripherals.GPIO12,
|
peripherals.GPIO10, // shared reset
|
||||||
|
peripherals.GPIO12, // shared dc
|
||||||
&mut delay,
|
&mut delay,
|
||||||
);
|
);
|
||||||
|
|
||||||
setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
|
setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
|
||||||
|
|
||||||
log::info!("Setup complete, entering main loop");
|
|
||||||
|
|
||||||
let mut nav_state = NavigationState::new();
|
let mut nav_state = NavigationState::new();
|
||||||
|
|
||||||
|
oled.clear(BinaryColor::Off).unwrap();
|
||||||
|
|
||||||
|
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
|
||||||
|
Text::new("Hello OLED", Point::new(10, 20), text_style)
|
||||||
|
.draw(&mut oled)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
oled.flush().unwrap();
|
||||||
|
|
||||||
|
|
||||||
let mut nfc_driver = NfcPn532Driver::new(peripherals.I2C0, peripherals.GPIO17, peripherals.GPIO18);
|
let mut nfc_driver = NfcPn532Driver::new(peripherals.I2C0, peripherals.GPIO17, peripherals.GPIO18);
|
||||||
let timeout = Duration::from_millis(1000);
|
let timeout = Duration::from_millis(1000);
|
||||||
if nfc_driver.configure_sam(timeout).is_ok() {
|
if nfc_driver.configure_sam(timeout).is_ok() {
|
||||||
@@ -93,6 +109,8 @@ async fn main(spawner: Spawner) {
|
|||||||
log::error!("NFC SAM configuration failed");
|
log::error!("NFC SAM configuration failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log::info!("Setup complete, entering main loop");
|
||||||
loop {
|
loop {
|
||||||
if let Ok(card_data) = nfc_driver.read_card_data() {
|
if let Ok(card_data) = nfc_driver.read_card_data() {
|
||||||
log::info!("NFC Card Read: {:?}", card_data);
|
log::info!("NFC Card Read: {:?}", card_data);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
pub mod palette;
|
pub mod palette;
|
||||||
pub mod primary_lcd;
|
pub mod primary_lcd;
|
||||||
pub mod secondary_oled;
|
pub mod secondary_oled;
|
||||||
|
pub mod shared_bus;
|
||||||
pub mod sprite;
|
pub mod sprite;
|
||||||
pub mod tertiary_lcd;
|
pub mod tertiary_lcd;
|
||||||
pub mod views;
|
pub mod views;
|
||||||
|
|
||||||
|
|||||||
+26
-36
@@ -1,54 +1,42 @@
|
|||||||
|
use core::cell::RefCell;
|
||||||
use display_interface_spi::SPIInterface;
|
use display_interface_spi::SPIInterface;
|
||||||
use embedded_graphics::draw_target::DrawTarget;
|
use embedded_graphics::draw_target::DrawTarget;
|
||||||
use embedded_graphics::pixelcolor::Rgb565;
|
use embedded_graphics::pixelcolor::Rgb565;
|
||||||
use embedded_graphics::prelude::RgbColor;
|
use embedded_graphics::prelude::RgbColor;
|
||||||
use embedded_hal_bus::spi::ExclusiveDevice;
|
use embedded_hal::digital::OutputPin as EhOutputPin;
|
||||||
|
use embedded_hal_bus::spi::RefCellDevice;
|
||||||
use esp_hal::delay::Delay;
|
use esp_hal::delay::Delay;
|
||||||
use esp_hal::gpio::{Level, Output, OutputConfig};
|
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin};
|
||||||
use esp_hal::peripherals::{GPIO10, GPIO11, GPIO12, GPIO35, GPIO36, GPIO37, SPI2};
|
|
||||||
use esp_hal::spi::{master::{Config, Spi}, Mode};
|
|
||||||
use esp_hal::time::Rate;
|
|
||||||
use ili9341::{DisplaySize240x320, Ili9341, Orientation};
|
use ili9341::{DisplaySize240x320, Ili9341, Orientation};
|
||||||
|
|
||||||
pub type PrimaryLcdDisplay<'a> = Ili9341<
|
pub type PrimaryLcdDisplay<'a, BUS, DC, RES> = Ili9341<
|
||||||
SPIInterface<
|
SPIInterface<
|
||||||
ExclusiveDevice<Spi<'a, esp_hal::Blocking>, Output<'a>, Delay>,
|
RefCellDevice<'a, BUS, Output<'a>, Delay>,
|
||||||
Output<'a>,
|
DC,
|
||||||
>,
|
>,
|
||||||
Output<'a>,
|
RES,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
pub fn init_primary_lcd(
|
pub fn init_primary_lcd_on_bus<'a, BUS, CS, RES, DC>(
|
||||||
spi2: SPI2<'static>,
|
spi_bus: &'a RefCell<BUS>,
|
||||||
sck: GPIO36<'static>,
|
cs: CS,
|
||||||
mosi: GPIO35<'static>,
|
reset: RES,
|
||||||
miso: GPIO37<'static>,
|
dc: DC,
|
||||||
cs: GPIO11<'static>,
|
|
||||||
reset: GPIO10<'static>,
|
|
||||||
dc: GPIO12<'static>,
|
|
||||||
delay: &mut Delay,
|
delay: &mut Delay,
|
||||||
) -> PrimaryLcdDisplay<'static> {
|
) -> PrimaryLcdDisplay<'a, BUS, DC, RES>
|
||||||
let freq = Rate::from_khz(60_000);
|
where
|
||||||
log::info!("Display freq: {freq}");
|
BUS: embedded_hal::spi::SpiBus,
|
||||||
|
CS: OutputPin + 'static,
|
||||||
let spi_bus = Spi::new(
|
RES: EhOutputPin,
|
||||||
spi2,
|
DC: EhOutputPin,
|
||||||
Config::default().with_frequency(freq).with_mode(Mode::_0),
|
{
|
||||||
)
|
let cs_pin = Output::new(cs, Level::High, OutputConfig::default());
|
||||||
.unwrap()
|
let spi_dev = RefCellDevice::new(spi_bus, cs_pin, *delay).unwrap();
|
||||||
.with_sck(sck)
|
let iface = SPIInterface::new(spi_dev, dc);
|
||||||
.with_mosi(mosi)
|
|
||||||
.with_miso(miso);
|
|
||||||
|
|
||||||
let cs_main = Output::new(cs, Level::High, OutputConfig::default());
|
|
||||||
let spi_dev = ExclusiveDevice::new(spi_bus, cs_main, *delay).unwrap();
|
|
||||||
let reset_main = Output::new(reset, Level::High, OutputConfig::default());
|
|
||||||
let spi_dc = Output::new(dc, Level::High, OutputConfig::default());
|
|
||||||
let iface = SPIInterface::new(spi_dev, spi_dc);
|
|
||||||
|
|
||||||
let mut display = Ili9341::new(
|
let mut display = Ili9341::new(
|
||||||
iface,
|
iface,
|
||||||
reset_main,
|
reset,
|
||||||
delay,
|
delay,
|
||||||
Orientation::Portrait,
|
Orientation::Portrait,
|
||||||
DisplaySize240x320,
|
DisplaySize240x320,
|
||||||
@@ -58,3 +46,5 @@ pub fn init_primary_lcd(
|
|||||||
display.clear(Rgb565::BLACK).unwrap();
|
display.clear(Rgb565::BLACK).unwrap();
|
||||||
display
|
display
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,54 @@
|
|||||||
// Secondary OLED module
|
use core::cell::RefCell;
|
||||||
|
use display_interface_spi::SPIInterface;
|
||||||
|
use embedded_graphics::pixelcolor::BinaryColor;
|
||||||
|
use embedded_graphics::prelude::*;
|
||||||
|
use embedded_hal::digital::OutputPin as EhOutputPin;
|
||||||
|
use embedded_hal_bus::spi::RefCellDevice;
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin};
|
||||||
|
use ssd1306::mode::BufferedGraphicsMode;
|
||||||
|
use ssd1306::prelude::*;
|
||||||
|
use ssd1306::Ssd1306;
|
||||||
|
|
||||||
|
pub type SecondaryOledDisplay<'a, BUS, DC> = Ssd1306<
|
||||||
|
SPIInterface<
|
||||||
|
RefCellDevice<'a, BUS, Output<'a>, Delay>,
|
||||||
|
DC,
|
||||||
|
>,
|
||||||
|
DisplaySize128x64,
|
||||||
|
BufferedGraphicsMode<DisplaySize128x64>,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub fn init_secondary_oled_on_bus<'a, BUS, CS, RES, DC>(
|
||||||
|
spi_bus: &'a RefCell<BUS>,
|
||||||
|
cs: CS,
|
||||||
|
mut res: RES,
|
||||||
|
dc: DC,
|
||||||
|
delay: &mut Delay,
|
||||||
|
) -> SecondaryOledDisplay<'a, BUS, DC>
|
||||||
|
where
|
||||||
|
BUS: embedded_hal::spi::SpiBus,
|
||||||
|
CS: OutputPin + 'static,
|
||||||
|
RES: EhOutputPin,
|
||||||
|
DC: EhOutputPin,
|
||||||
|
{
|
||||||
|
let cs_pin = Output::new(cs, Level::High, OutputConfig::default());
|
||||||
|
let spi_dev = RefCellDevice::new(spi_bus, cs_pin, *delay).unwrap();
|
||||||
|
let interface = SPIInterface::new(spi_dev, dc);
|
||||||
|
|
||||||
|
let mut display = Ssd1306::new(
|
||||||
|
interface,
|
||||||
|
DisplaySize128x64,
|
||||||
|
DisplayRotation::Rotate0,
|
||||||
|
)
|
||||||
|
.into_buffered_graphics_mode();
|
||||||
|
|
||||||
|
display.reset(&mut res, delay).unwrap();
|
||||||
|
display.init().unwrap();
|
||||||
|
display.clear(BinaryColor::Off).unwrap();
|
||||||
|
display.flush().unwrap();
|
||||||
|
|
||||||
|
display
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
use alloc::boxed::Box;
|
||||||
|
use core::cell::RefCell;
|
||||||
|
use embedded_hal::digital::{ErrorType, OutputPin as EhOutputPin, PinState};
|
||||||
|
use esp_hal::delay::Delay;
|
||||||
|
use esp_hal::gpio::interconnect::{PeripheralInput, PeripheralOutput};
|
||||||
|
use esp_hal::gpio::{Level, Output, OutputConfig, OutputPin};
|
||||||
|
use esp_hal::spi::master::{Config as SpiConfig, Spi};
|
||||||
|
use esp_hal::spi::Mode;
|
||||||
|
use esp_hal::time::Rate;
|
||||||
|
use crate::display::primary_lcd::{init_primary_lcd_on_bus, PrimaryLcdDisplay};
|
||||||
|
|
||||||
|
use crate::display::secondary_oled::{init_secondary_oled_on_bus, SecondaryOledDisplay};
|
||||||
|
|
||||||
|
pub struct SharedPin<'a>(pub &'a RefCell<Output<'static>>);
|
||||||
|
|
||||||
|
impl<'a> ErrorType for SharedPin<'a> {
|
||||||
|
type Error = core::convert::Infallible;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> EhOutputPin for SharedPin<'a> {
|
||||||
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.borrow_mut().set_low();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||||
|
self.0.borrow_mut().set_high();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_state(&mut self, state: PinState) -> Result<(), Self::Error> {
|
||||||
|
self.0.borrow_mut().set_state(state);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DisplaySpiBus = Spi<'static, esp_hal::Blocking>;
|
||||||
|
pub type DualPrimaryDisplay<'a> = PrimaryLcdDisplay<'a, DisplaySpiBus, SharedPin<'a>, SharedPin<'a>>;
|
||||||
|
pub type DualSecondaryDisplay<'a> = SecondaryOledDisplay<'a, DisplaySpiBus, SharedPin<'a>>;
|
||||||
|
|
||||||
|
pub fn init_dual_displays<SPI, SCK, MOSI, MISO, CS1, CS2, RES, DC>(
|
||||||
|
spi_peripheral: SPI,
|
||||||
|
sck: SCK,
|
||||||
|
mosi: MOSI,
|
||||||
|
miso: MISO,
|
||||||
|
cs_primary: CS1,
|
||||||
|
cs_secondary: CS2,
|
||||||
|
reset_pin: RES,
|
||||||
|
dc_pin: DC,
|
||||||
|
delay: &mut Delay,
|
||||||
|
) -> (DualPrimaryDisplay<'static>, DualSecondaryDisplay<'static>)
|
||||||
|
|
||||||
|
where
|
||||||
|
SPI: esp_hal::spi::master::Instance + 'static,
|
||||||
|
SCK: PeripheralOutput<'static>,
|
||||||
|
MOSI: PeripheralOutput<'static>,
|
||||||
|
MISO: PeripheralInput<'static>,
|
||||||
|
CS1: OutputPin + 'static,
|
||||||
|
CS2: OutputPin + 'static,
|
||||||
|
RES: OutputPin + 'static,
|
||||||
|
DC: OutputPin + 'static,
|
||||||
|
{
|
||||||
|
let spi = Spi::new(
|
||||||
|
spi_peripheral,
|
||||||
|
SpiConfig::default().with_frequency(Rate::from_khz(20_000)).with_mode(Mode::_0),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.with_sck(sck)
|
||||||
|
.with_mosi(mosi)
|
||||||
|
.with_miso(miso);
|
||||||
|
|
||||||
|
let bus_static: &'static RefCell<DisplaySpiBus> = Box::leak(Box::new(RefCell::new(spi)));
|
||||||
|
let reset_static: &'static RefCell<Output<'static>> = Box::leak(Box::new(RefCell::new(
|
||||||
|
Output::new(reset_pin, Level::High, OutputConfig::default()),
|
||||||
|
)));
|
||||||
|
let dc_static: &'static RefCell<Output<'static>> = Box::leak(Box::new(RefCell::new(
|
||||||
|
Output::new(dc_pin, Level::High, OutputConfig::default()),
|
||||||
|
)));
|
||||||
|
|
||||||
|
let primary = init_primary_lcd_on_bus(
|
||||||
|
bus_static,
|
||||||
|
cs_primary,
|
||||||
|
SharedPin(reset_static),
|
||||||
|
SharedPin(dc_static),
|
||||||
|
delay,
|
||||||
|
);
|
||||||
|
|
||||||
|
let secondary = init_secondary_oled_on_bus(
|
||||||
|
bus_static,
|
||||||
|
cs_secondary,
|
||||||
|
SharedPin(reset_static),
|
||||||
|
SharedPin(dc_static),
|
||||||
|
delay,
|
||||||
|
);
|
||||||
|
|
||||||
|
(primary, secondary)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user