use embassy_time::{Duration, Timer};
use thiserror_no_std::Error;
use crate::io::shared_i2c::SharedI2cBus;
pub const ADDR: u8 = 0x58;
const REG_OUTPUT_P0: u8 = 0x02;
const REG_OUTPUT_P1: u8 = 0x03;
const REG_CONFIG_P0: u8 = 0x04;
const REG_CONFIG_P1: u8 = 0x05;
const REG_GCR: u8 = 0x11; const REG_LEDMODE_P0: u8 = 0x12;
const REG_LEDMODE_P1: u8 = 0x13;
const GCR_P0_PUSH_PULL: u8 = 0x10;
pub const P0_TOUCH_RST: u8 = 0x01; pub const P0_BUS_OUT_EN: u8 = 0x02; #[allow(dead_code)]
pub const P0_AW_RST: u8 = 0x04;
pub const P1_CAM_RST: u8 = 0x01; pub const P1_LCD_RST: u8 = 0x02; pub const P1_BOOST_EN: u8 = 0x80; #[allow(dead_code)]
pub const P1_TOUCH_INT: u8 = 0x04; #[allow(dead_code)]
pub const P1_AW_INT: u8 = 0x08;
const CONFIG_P1_VAL: u8 = !(P1_CAM_RST | P1_LCD_RST);
#[derive(Debug, Error)]
pub enum Aw9523bError {
#[error("I2C error: {0:?}")]
I2cError(#[from] esp_hal::i2c::master::Error),
}
pub struct Aw9523bDriver {
i2c: &'static SharedI2cBus,
address: u8,
}
pub struct Aw9523bResources {
pub i2c: &'static SharedI2cBus,
}
impl Aw9523bDriver {
pub fn new(res: Aw9523bResources) -> Self {
Self {
i2c: res.i2c,
address: ADDR,
}
}
async fn read_reg(&mut self, reg: u8) -> Result<u8, Aw9523bError> {
let mut buf = [0u8];
self.i2c
.lock()
.await
.write_read_async(self.address, &[reg], &mut buf)
.await?;
Ok(buf[0])
}
async fn write_reg(&mut self, reg: u8, value: u8) -> Result<(), Aw9523bError> {
self.i2c
.lock()
.await
.write_async(self.address, &[reg, value])
.await?;
Ok(())
}
async fn set_bits(&mut self, reg: u8, mask: u8) -> Result<(), Aw9523bError> {
let val = self.read_reg(reg).await?;
self.write_reg(reg, val | mask).await
}
async fn clear_bits(&mut self, reg: u8, mask: u8) -> Result<(), Aw9523bError> {
let val = self.read_reg(reg).await?;
self.write_reg(reg, val & !mask).await
}
pub async fn init(&mut self) -> Result<(), Aw9523bError> {
self.set_bits(REG_OUTPUT_P0, P0_TOUCH_RST).await?;
self.set_bits(REG_LEDMODE_P0, P0_TOUCH_RST).await?; self.clear_bits(REG_CONFIG_P0, P0_TOUCH_RST).await?; self.write_reg(REG_LEDMODE_P1, 0xFF).await?;
self.write_reg(REG_OUTPUT_P1, P1_CAM_RST | P1_LCD_RST)
.await?;
self.write_reg(REG_CONFIG_P1, CONFIG_P1_VAL).await?;
Ok(())
}
pub async fn lcd_rst_pulse(&mut self) -> Result<(), Aw9523bError> {
self.write_reg(REG_OUTPUT_P1, P1_CAM_RST).await?; Timer::after(Duration::from_micros(10)).await;
self.write_reg(REG_OUTPUT_P1, P1_CAM_RST | P1_LCD_RST)
.await?;
Timer::after(Duration::from_millis(120)).await;
Ok(())
}
pub async fn enable_bus_5v(&mut self) -> Result<(), Aw9523bError> {
self.set_bits(REG_LEDMODE_P1, P1_BOOST_EN).await?; self.set_bits(REG_OUTPUT_P1, P1_BOOST_EN).await?; self.clear_bits(REG_CONFIG_P1, P1_BOOST_EN).await?; self.set_bits(REG_GCR, GCR_P0_PUSH_PULL).await?;
self.set_bits(REG_LEDMODE_P0, P0_BUS_OUT_EN).await?;
self.set_bits(REG_OUTPUT_P0, P0_BUS_OUT_EN).await?;
self.clear_bits(REG_CONFIG_P0, P0_BUS_OUT_EN).await?;
Ok(())
}
pub async fn touch_rst_pulse(&mut self) -> Result<(), Aw9523bError> {
self.clear_bits(REG_OUTPUT_P0, P0_TOUCH_RST).await?;
Timer::after(Duration::from_millis(5)).await;
self.set_bits(REG_OUTPUT_P0, P0_TOUCH_RST).await?;
Timer::after(Duration::from_millis(300)).await;
Ok(())
}
}