99 lines
2.9 KiB
Rust
99 lines
2.9 KiB
Rust
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)
|
|
}
|
|
|