use embedded_hal::digital::{ErrorType, OutputPin};
use esp_hal::{
Blocking,
dma::DmaChannelConvert,
gpio::AnyPin,
i2c::master::{BusTimeout, Config as I2cConfig, I2c, SoftwareTimeout},
interrupt::software::SoftwareInterruptControl,
peripherals::{BT, PCNT, Peripherals, RMT, USB_DEVICE, WIFI},
spi::master::AnySpi,
time::Rate,
timer::{AnyTimer, timg::TimerGroup},
};
use crate::board::SystemResources;
use crate::board::spi2::Spi2Resources;
use crate::driver::aw9523b::{Aw9523bDriver, Aw9523bResources};
use crate::driver::axp2101::Axp2101Driver;
use crate::io::shared_i2c::SharedI2cBus;
const AXP2101_ADDR: u8 = 0x34;
const BACKLIGHT_MV: u16 = 3300;
pub async fn power_display_reset(i2c: &'static SharedI2cBus) {
let mut aw = Aw9523bDriver::new(Aw9523bResources { i2c });
if let Err(e) = aw.init().await {
error!("AW9523B init failed: {:?}", e);
}
if let Err(e) = aw.lcd_rst_pulse().await {
error!("AW9523B LCD RST failed: {:?}", e);
}
if let Err(e) = aw.touch_rst_pulse().await {
error!("AW9523B TOUCH RST failed: {:?}", e);
}
let mut axp = Axp2101Driver::new(i2c, AXP2101_ADDR);
if let Err(e) = axp.set_dldo1(true, BACKLIGHT_MV).await {
error!("AXP2101 backlight enable failed: {:?}", e);
}
}
const GPIO35_BIT: u32 = 1 << (35 - 32);
pub struct Gpio35Dc;
impl ErrorType for Gpio35Dc {
type Error = core::convert::Infallible;
}
impl OutputPin for Gpio35Dc {
fn set_low(&mut self) -> Result<(), Self::Error> {
unsafe {
let gpio = &*esp_hal::peripherals::GPIO::PTR;
gpio.out1_w1tc().write(|w| w.bits(GPIO35_BIT));
gpio.enable1_w1ts().write(|w| w.bits(GPIO35_BIT));
}
Ok(())
}
fn set_high(&mut self) -> Result<(), Self::Error> {
unsafe {
let gpio = &*esp_hal::peripherals::GPIO::PTR;
gpio.out1_w1ts().write(|w| w.bits(GPIO35_BIT));
gpio.enable1_w1ts().write(|w| w.bits(GPIO35_BIT));
}
Ok(())
}
}
pub fn gpio35_disable_output() {
unsafe {
let gpio = &*esp_hal::peripherals::GPIO::PTR;
gpio.enable1_w1tc().write(|w| w.bits(GPIO35_BIT));
}
}
pub struct M5Bus<'a> {
pub gpio1: AnyPin<'a>,
pub gpio9: AnyPin<'a>,
}
pub struct Board {
pub spi2: Spi2Resources<'static>,
pub i2c0: I2c<'static, Blocking>,
pub bt: BT<'static>,
pub wifi: WIFI<'static>,
pub usb_device: USB_DEVICE<'static>,
pub rmt: RMT<'static>,
pub pcnt: PCNT<'static>,
pub sk6812: AnyPin<'static>,
pub psram: esp_hal::peripherals::PSRAM<'static>,
pub m5bus: M5Bus<'static>,
pub system: SystemResources<'static>,
}
impl Board {
pub fn split(peripherals: Peripherals) -> Self {
let spi2 = Spi2Resources {
spi2: AnySpi::from(peripherals.SPI2),
spi2_dma: peripherals.DMA_CH0.degrade(),
sck: AnyPin::from(peripherals.GPIO36),
mosi: AnyPin::from(peripherals.GPIO37),
miso_dc: AnyPin::from(peripherals.GPIO35),
display_cs: AnyPin::from(peripherals.GPIO3),
card_cs: AnyPin::from(peripherals.GPIO4),
};
let i2c0 = I2c::new(
peripherals.I2C0,
I2cConfig::default()
.with_frequency(Rate::from_khz(400))
.with_timeout(BusTimeout::BusCycles(20))
.with_software_timeout(SoftwareTimeout::Transaction(
esp_hal::time::Duration::from_millis(25),
)),
)
.expect("I2C0 init failed")
.with_sda(AnyPin::from(peripherals.GPIO12))
.with_scl(AnyPin::from(peripherals.GPIO11));
let tg0 = TimerGroup::new(peripherals.TIMG0);
let tg1 = TimerGroup::new(peripherals.TIMG1);
let system = SystemResources {
sw_int: SoftwareInterruptControl::new(peripherals.SW_INTERRUPT),
timer0_0: AnyTimer::from(tg0.timer0),
timer0_1: AnyTimer::from(tg0.timer1),
timer1_0: AnyTimer::from(tg1.timer0),
timer1_1: AnyTimer::from(tg1.timer1),
cpu_ctrl: peripherals.CPU_CTRL,
lpwr: peripherals.LPWR,
};
Board {
spi2,
i2c0,
bt: peripherals.BT,
wifi: peripherals.WIFI,
usb_device: peripherals.USB_DEVICE,
rmt: peripherals.RMT,
pcnt: peripherals.PCNT,
sk6812: AnyPin::from(peripherals.GPIO13),
psram: peripherals.PSRAM,
m5bus: M5Bus {
gpio1: AnyPin::from(peripherals.GPIO1),
gpio9: AnyPin::from(peripherals.GPIO9),
},
system,
}
}
}