use esp_hal::Blocking;
use gc9a01::{mode::BufferedGraphics, prelude::*, Gc9a01, SPIDisplayInterface};
use esp_hal::delay::Delay;
use esp_hal::gpio::{Input, Level, Output, Pull};
use esp_hal::spi::{
master::{Config, Spi},
Mode,
};
use esp_hal::time::RateExtU32;
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
use rotary_encoder_hal::{DefaultPhase, Rotary};
use defmt::error;
pub struct M5DialBsp {
pub display: Gc9a01<
SPIInterface<
ExclusiveDevice<Spi<'static, Blocking>, Output<'static>, NoDelay>,
Output<'static>,
>,
DisplayResolution240x240,
BufferedGraphics<DisplayResolution240x240>,
>,
display_bl: Output<'static>,
pub encoder: Rotary<Input<'static>, Input<'static>, DefaultPhase>,
hold: Output<'static>,
wake: Input<'static>,
last_wake_state: bool,
}
pub fn init(peripherals: esp_hal::peripherals::Peripherals) -> M5DialBsp {
let mut delay = Delay::new();
let spi = Spi::new(
peripherals.SPI2,
Config::default()
.with_frequency(50.MHz())
.with_mode(Mode::_0),
)
.unwrap()
.with_sck(peripherals.GPIO6)
.with_mosi(peripherals.GPIO5);
let cs = Output::new(peripherals.GPIO7, Level::High);
let rs = Output::new(peripherals.GPIO4, Level::High);
let display_dev = ExclusiveDevice::new_no_delay(spi, cs).unwrap();
let display_iface = SPIDisplayInterface::new(display_dev, rs);
let mut display = Gc9a01::new(
display_iface,
DisplayResolution240x240,
DisplayRotation::Rotate180,
)
.into_buffered_graphics();
let mut display_reset = Output::new(peripherals.GPIO8, Level::High);
if display.reset(&mut display_reset, &mut delay).is_err() {
error!("Display reset error");
loop {}
}
if display.init(&mut delay).is_err() {
error!("Display Init error");
loop {}
}
display.clear();
display.fill(0x0);
if display.flush().is_err() {
error!("Display flush error");
}
let pin_a = Input::new(peripherals.GPIO41, Pull::None);
let pin_b = Input::new(peripherals.GPIO40, Pull::None);
let encoder = Rotary::new(pin_a, pin_b);
let bl = Output::new(peripherals.GPIO9, Level::Low);
let hold = Output::new(peripherals.GPIO46, Level::High);
let wake = Input::new(peripherals.GPIO42, Pull::None);
let wake_state = wake.is_low();
M5DialBsp {
display: display,
display_bl: bl,
encoder: encoder,
hold: hold,
wake: wake,
last_wake_state: wake_state,
}
}
impl M5DialBsp {
pub fn set_backlight(&mut self, state: bool) {
if state {
self.display_bl.set_high();
} else {
self.display_bl.set_low();
}
}
pub fn shutdown(&mut self) {
self.hold.set_low();
}
pub fn is_button_pushed(&mut self) -> bool {
self.last_wake_state = self.wake.is_low();
self.last_wake_state
}
pub fn has_button_changed(&mut self) -> Option<bool> {
let current_state = self.wake.is_low();
if current_state != self.last_wake_state {
self.last_wake_state = current_state;
Some(current_state)
} else {
None
}
}
}