pub use defmt::error;
pub use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
pub use esp_hal::{
delay::Delay,
gpio::{Input, InputConfig, Level, Output, OutputConfig, OutputPin, Pull},
i2c::master::{Config as I2cConfig, I2c as EspI2C},
ledc::Ledc,
spi::{
master::{Config as SpiConfig, Spi},
Mode,
},
time::Rate,
Blocking,
};
pub use gc9a01::{mode::BufferedGraphics, prelude::*, Gc9a01, SPIDisplayInterface};
pub use crate::ft3267::{Ft3267, TouchPoint};
pub use rotary_encoder_hal::{DefaultPhase, Rotary};
pub use crate::buzzer::Buzzer;
pub type M5DialDisplay = Gc9a01<
SPIInterface<
ExclusiveDevice<Spi<'static, Blocking>, Output<'static>, NoDelay>,
Output<'static>,
>,
DisplayResolution240x240,
BufferedGraphics<DisplayResolution240x240>,
>;
pub type M5DialEncoder = Rotary<Input<'static>, Input<'static>, DefaultPhase>;
pub struct TouchControl {
tp_i2c: EspI2C<'static, Blocking>,
touch: Ft3267,
}
pub struct M5DialBsp {
display_bl: Output<'static>,
hold: Output<'static>,
wake: Input<'static>,
last_wake_state: bool,
}
#[macro_export]
macro_rules! get_encoder {
($peripherals:ident) => {{
let pin_a = Input::new($peripherals.GPIO41, InputConfig::default());
let pin_b = Input::new($peripherals.GPIO40, InputConfig::default());
Rotary::new(pin_a, pin_b)
}};
}
#[macro_export]
macro_rules! get_screen {
($peripherals:ident) => {{
let mut delay = Delay::new();
let spi = Spi::new(
$peripherals.SPI2,
SpiConfig::default()
.with_frequency(Rate::from_mhz(50))
.with_mode(Mode::_0),
)
.unwrap()
.with_sck($peripherals.GPIO6)
.with_mosi($peripherals.GPIO5);
let cs = Output::new($peripherals.GPIO7, Level::High, OutputConfig::default());
let rs = Output::new($peripherals.GPIO4, Level::High, OutputConfig::default());
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, OutputConfig::default());
if display.reset(&mut display_reset, &mut delay).is_err() {
panic!("Display reset error");
}
if display.init(&mut delay).is_err() {
panic!("Display Init error");
}
display.clear();
display.fill(0x0);
if display.flush().is_err() {
error!("Display flush error");
}
display
}};
}
#[macro_export]
macro_rules! get_touch {
($peripherals:ident) => {{
let mut tp_i2c = EspI2C::new($peripherals.I2C0, I2cConfig::default())
.expect("Failed to get I2C0")
.with_sda($peripherals.GPIO11)
.with_scl($peripherals.GPIO12);
let touch = Ft3267::new(0);
touch.init(&mut tp_i2c);
TouchControl::new(tp_i2c, touch)
}};
}
#[macro_export]
macro_rules! get_port_a_i2c {
($peripherals:ident) => {{
EspI2C::new($peripherals.I2C1, I2cConfig::default())
.expect("Failed to get I2C1")
.with_sda($peripherals.GPIO13)
.with_scl($peripherals.GPIO15);
}};
}
#[macro_export]
macro_rules! get_port_b_in {
($peripherals:ident, $input_config:expr) => {{
Input::new($peripherals.GPIO1, $input_config)
}};
}
#[macro_export]
macro_rules! get_port_b_out {
($peripherals:ident) => {{
Output::new($peripherals.GPIO2, Level::Low)
}};
}
#[macro_export]
macro_rules! get_buzzer {
($peripherals:ident) => {
Buzzer::new(Ledc::new($peripherals.LEDC), $peripherals.GPIO3.into())
};
}
#[macro_export]
macro_rules! board_init {
($peripherals:ident) => {
M5DialBsp::new(
Output::new($peripherals.GPIO9, Level::Low, OutputConfig::default()),
Output::new($peripherals.GPIO46, Level::High, OutputConfig::default()),
Input::new($peripherals.GPIO42, InputConfig::default()),
)
};
}
impl M5DialBsp {
pub fn new(bl: Output<'static>, hold: Output<'static>, wake: Input<'static>) -> M5DialBsp {
let wake_state = wake.is_low();
M5DialBsp {
display_bl: bl,
hold,
wake,
last_wake_state: wake_state,
}
}
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
}
}
}
impl TouchControl {
pub fn new(tp_i2c: EspI2C<'static, Blocking>, touch: Ft3267) -> TouchControl {
TouchControl { tp_i2c, touch }
}
pub fn count(&mut self) -> Option<u8> {
let touch_count = self.touch.pool(&mut self.tp_i2c);
if touch_count > 0 {
Some(touch_count)
} else {
None
}
}
pub fn position(&mut self, n: u8) -> TouchPoint {
self.touch.get_point(&mut self.tp_i2c, n)
}
}