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::{
channel::{self, Channel, ChannelHW, ChannelIFace},
timer::{self, Timer, TimerIFace},
LSGlobalClkSource, Ledc, LowSpeed,
},
rmt::Rmt,
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 crate::rtc8563::{Rtc8563, RTC8563_DEFAULT_I2C_ADDRESS};
pub use rotary_encoder_hal::{DefaultPhase, Rotary};
pub use crate::buzzer::Buzzer;
pub use crate::backlight::M5DialBackLight;
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 M5DialBsp {
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 {
($tp_i2c:ident) => {{
let touch = Ft3267::new(0);
let _ = touch.init(&mut $tp_i2c);
touch
}};
}
#[macro_export]
macro_rules! get_rtc {
($tp_i2c:ident) => {{
let rtc = Rtc8563::new(RTC8563_DEFAULT_I2C_ADDRESS);
rtc.init(&mut $tp_i2c);
rtc
}};
}
#[macro_export]
macro_rules! get_internal_i2C {
($peripherals:ident) => {{
EspI2C::new($peripherals.I2C0, I2cConfig::default())
.expect("Failed to get I2C0")
.with_sda($peripherals.GPIO11)
.with_scl($peripherals.GPIO12)
}};
}
#[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(
Rmt::new($peripherals.RMT, Rate::from_mhz(80)).unwrap(),
$peripherals.GPIO3.into(),
)
};
}
#[macro_export]
macro_rules! board_init {
($peripherals:ident) => {
M5DialBsp::new(
Output::new($peripherals.GPIO46, Level::High, OutputConfig::default()),
Input::new($peripherals.GPIO42, InputConfig::default()),
)
};
}
#[macro_export]
macro_rules! make_display_backlight {
($name:ident, $peripherals:ident) => {
let mut ledc = Ledc::new($peripherals.LEDC);
ledc.set_global_slow_clock(LSGlobalClkSource::APBClk);
let mut lstimer0 = ledc.timer::<LowSpeed>(timer::Number::Timer0);
lstimer0
.configure(timer::config::Config {
duty: timer::config::Duty::Duty5Bit,
clock_source: timer::LSClockSource::APBClk,
frequency: Rate::from_khz(24),
})
.expect("Fail to configure timer");
let mut $name = M5DialBackLight::new(
Output::new($peripherals.GPIO9, Level::Low, OutputConfig::default()),
&ledc,
&lstimer0,
);
};
}
impl M5DialBsp {
pub fn new(hold: Output<'static>, wake: Input<'static>) -> Self {
let wake_state = wake.is_low();
M5DialBsp {
hold,
wake,
last_wake_state: wake_state,
}
}
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
}
}
}