diff --git a/firmware/acid-firmware/Cargo.toml b/firmware/acid-firmware/Cargo.toml index 02e1447..624cbde 100644 --- a/firmware/acid-firmware/Cargo.toml +++ b/firmware/acid-firmware/Cargo.toml @@ -84,7 +84,7 @@ serde = { version = "1.0", default-features = false, features = ["derive"] } # serde_with = { version = "3.16", default-features = false, features = ["alloc", "macros"] } serde_bytes = { version = "0.11.19", default-features = false, features = ["alloc"] } chrono = { version = "0.4.43", default-features = false, features = ["alloc", "serde"] } # TODO: defmt -tinyvec = { version = "1.10.0", default-features = false, features = ["alloc"] } +tinyvec = { version = "1.10.0", default-features = false, features = ["alloc", "latest_stable_rust"] } esp-metadata-generated = { version = "0.3.0", features = ["esp32s3"] } hex = { version = "0.4.3", default-features = false, features = ["alloc"] } indoc = "2.0.7" diff --git a/firmware/acid-firmware/src/peripherals/st7701s/commands.rs b/firmware/acid-firmware/src/peripherals/st7701s/commands.rs index 4e3a5ee..b0e78be 100644 --- a/firmware/acid-firmware/src/peripherals/st7701s/commands.rs +++ b/firmware/acid-firmware/src/peripherals/st7701s/commands.rs @@ -1,40 +1,41 @@ use paste::paste; -// use tinyvec::ArrayVec; +use tinyvec::ArrayVec; pub trait Command { fn address(&self) -> u8; fn args_iter(&'_ self) -> core::slice::Iter<'_, u8>; } -// pub struct ArrayCommand { -// pub address: u8, -// pub args: ArrayVec<[u8; N]>, -// } +pub struct ArrayCommand { + pub address: u8, + pub args: ArrayVec<[u8; N]>, +} -// impl const ArrayCommand { -// const fn from(command: impl Command) -> Self { -// Self { -// address: command.address(), -// args: command.args_iter().copied().collect(), -// } -// } -// } +impl Command for ArrayCommand { + fn address(&self) -> u8 { + self.address + } -// impl Command for ArrayCommand { -// fn address(&self) -> u8 { -// self.address -// } - -// fn args_iter(&'_ self) -> core::slice::Iter<'_, u8> { -// self.args.iter() -// } -// } + fn args_iter(&'_ self) -> core::slice::Iter<'_, u8> { + self.args.iter() + } +} pub struct CustomCommand { pub address: u8, pub args: &'static [u8], } +impl CustomCommand { + pub const fn address_const(&self) -> u8 { + self.address + } + + pub const fn args_slice(&self) -> &[u8] { + self.args + } +} + impl Command for CustomCommand { fn address(&self) -> u8 { self.address @@ -158,6 +159,21 @@ macro_rules! define_commands { $(#[$docs])* $visibility struct [< Cmd $command >]($(pub [< Cmd $command Arg ${index()} >], $(${ignore($body)})*)*); + impl [< Cmd $command >] { + pub const fn address_const(&self) -> u8 { + $address + } + + pub const fn args_slice(&self) -> &[u8] { + unsafe { + core::slice::from_raw_parts( + self as *const [< Cmd $command >] as *const u8, + 0 $(+ 1 $(${ignore($body)})*)*, + ) + } + } + } + impl Command for [< Cmd $command >] { fn address(&self) -> u8 { $address @@ -173,12 +189,7 @@ macro_rules! define_commands { type IntoIter = core::slice::Iter<'a, u8>; fn into_iter(self) -> Self::IntoIter { - unsafe { - core::slice::from_raw_parts( - self as *const [< Cmd $command >] as *const u8, - 0 $(+ 1 $(${ignore($body)})*)*, - ) - }.iter() + self.args_slice().iter() } } )* diff --git a/firmware/acid-firmware/src/peripherals/st7701s/init_sequence.rs b/firmware/acid-firmware/src/peripherals/st7701s/init_sequence.rs index 9cef7d5..2fd7126 100644 --- a/firmware/acid-firmware/src/peripherals/st7701s/init_sequence.rs +++ b/firmware/acid-firmware/src/peripherals/st7701s/init_sequence.rs @@ -1,377 +1,405 @@ -use alloc::{boxed::Box, vec, vec::Vec}; -use lazy_static::lazy_static; +use tinyvec::ArrayVec; use crate::peripherals::st7701s::commands::*; -// struct InitSequenceAction { -// command: ArrayCommand<8>, -// sleep: u64, -// } - -lazy_static! { - pub static ref INIT_SEQUENCE_COMMANDS: Vec<(Vec>, u64)> = vec![ - (vec![ - Box::new(CmdCn2bkxsel( - CmdCn2bkxselArg0::new(), - CmdCn2bkxselArg1::new(), - CmdCn2bkxselArg2::new(), - CmdCn2bkxselArg3::new(), - CmdCn2bkxselArg4::new().with_bksel(0x3).with_cn2(true), - )), - Box::new(CustomCommand { - address: 0xEF, - args: &[0x08], - }), - Box::new(CmdCn2bkxsel( - CmdCn2bkxselArg0::new(), - CmdCn2bkxselArg1::new(), - CmdCn2bkxselArg2::new(), - CmdCn2bkxselArg3::new(), - CmdCn2bkxselArg4::new().with_bksel(0x0).with_cn2(true), - )), - Box::new(CmdLneset( - CmdLnesetArg0::new().with_bar(119).with_lde_en(false), - CmdLnesetArg1::new().with_line_delta(0), - )), - Box::new(CmdPorctrl( - CmdPorctrlArg0::new().with_vbp(17), - CmdPorctrlArg1::new().with_vfp(12), - )), - Box::new(CmdInvsel( - CmdInvselArg0::new().with_nlinv(0b111), - CmdInvselArg1::new().with_rtni(2), - )), - Box::new(CustomCommand { - address: 0xCC, - args: &[0x30], - }), - Box::new(CmdPvgamctrl( - CmdPvgamctrlArg0::new().with_vc0p(6).with_aj0p(0), - CmdPvgamctrlArg1::new().with_vc4p(15).with_aj1p(3), - CmdPvgamctrlArg2::new().with_vc8p(14).with_aj2p(0), - CmdPvgamctrlArg3::new().with_vc16p(12), - CmdPvgamctrlArg4::new().with_vc24p(15).with_aj3p(0), - CmdPvgamctrlArg5::new().with_vc52p(3), - CmdPvgamctrlArg6::new().with_vc80p(0), - CmdPvgamctrlArg7::new().with_vc108p(10), - CmdPvgamctrlArg8::new().with_vc147p(7), - CmdPvgamctrlArg9::new().with_vc175p(27), - CmdPvgamctrlArg10::new().with_vc203p(3), - CmdPvgamctrlArg11::new().with_vc231p(18).with_aj4p(0), - CmdPvgamctrlArg12::new().with_vc239p(16), - CmdPvgamctrlArg13::new().with_vc247p(37).with_aj5p(0), - CmdPvgamctrlArg14::new().with_vc251p(54).with_aj6p(0), - CmdPvgamctrlArg15::new().with_vc255p(30).with_aj7p(0), - )), - Box::new(CmdNvgamctrl( - CmdNvgamctrlArg0::new().with_vc0n(12).with_aj0n(0), - CmdNvgamctrlArg1::new().with_vc4n(14).with_aj1n(3), - CmdNvgamctrlArg2::new().with_vc8n(18).with_aj2n(0), - CmdNvgamctrlArg3::new().with_vc16n(12), - CmdNvgamctrlArg4::new().with_vc24n(14).with_aj3n(0), - CmdNvgamctrlArg5::new().with_vc52n(6), - CmdNvgamctrlArg6::new().with_vc80n(3), - CmdNvgamctrlArg7::new().with_vc108n(6), - CmdNvgamctrlArg8::new().with_vc147n(8), - CmdNvgamctrlArg9::new().with_vc175n(35), - CmdNvgamctrlArg10::new().with_vc203n(6), - CmdNvgamctrlArg11::new().with_vc231n(18).with_aj4n(0), - CmdNvgamctrlArg12::new().with_vc239n(16), - CmdNvgamctrlArg13::new().with_vc247n(48).with_aj5n(0), - CmdNvgamctrlArg14::new().with_vc251n(47).with_aj6n(0), - CmdNvgamctrlArg15::new().with_vc255n(31).with_aj7n(0), - )), - Box::new(CmdCn2bkxsel( - CmdCn2bkxselArg0::new(), - CmdCn2bkxselArg1::new(), - CmdCn2bkxselArg2::new(), - CmdCn2bkxselArg3::new(), - CmdCn2bkxselArg4::new().with_bksel(0x1).with_cn2(true), - )), - Box::new(CmdVrhs( - CmdVrhsArg0::new().with_vrha(115), - )), - Box::new(CmdVcoms( - CmdVcomsArg0::new().with_vcom(124), - )), - Box::new(CmdVghss( - // The first bit is set to 1 in the original init code, but not here. - CmdVghssArg0::new().with_vghss(0x3), // 13 V - )), - Box::new(CmdTescmd( - CmdTescmdArg0::new(), - )), - Box::new(CmdVgls( - CmdVglsArg0::new().with_vgls(0x9) // -10.17 V - )), - Box::new(CmdPwctrl1( - CmdPwctrl1Arg0::new() - .with_apos(0x3) // Max - .with_apis(0x1) // Min - .with_ap(0x2) // Middle - )), - Box::new(CmdPwctrl2( - CmdPwctrl2Arg0::new() - .with_avcl(0x3) // -5 V - .with_avdd(0x3) // 6.8 V - )), - Box::new(CmdPwctrl3( - CmdPwctrl3Arg0::new() - .with_svno_pum(0) // Cell setting 4 - .with_svpo_pum(0x1) // Cell setting 5 - )), - Box::new(CmdPclks2( - CmdPclks2Arg0::new().with_sbstcks(0x3) - )), - Box::new(CmdPdr1( - CmdPdr1Arg0::new().with_t2d(8) // 1.6 us - )), - Box::new(CmdPdr2( - CmdPdr2Arg0::new().with_t3d(8) // 6.4 us - )), - Box::new(CmdMipiset1( - CmdMipiset1Arg0::new().with_err_sel(0).with_eotp_en(true), - )), - Box::new(CustomCommand { - address: 0xE0, - args: &[ - 0x00, - 0x00, - 0x02, - 0x00, - 0x00, - 0x0C, - ] - }), - Box::new(CustomCommand { - address: 0xE1, - args: &[ - 0x05, - 0x96, - 0x07, - 0x96, - 0x06, - 0x96, - 0x08, - 0x96, - 0x00, - 0x44, - 0x44, - ] - }), - Box::new(CustomCommand { - address: 0xE2, - args: &[ - 0x00, - 0x00, - 0x03, - 0x03, - 0x00, - 0x00, - 0x02, - 0x00, - 0x00, - 0x00, - 0x02, - 0x00, - ] - }), - Box::new(CustomCommand { - address: 0xE3, - args: &[ - 0x00, - 0x00, - 0x33, - 0x33, - ] - }), - Box::new(CustomCommand { - address: 0xE4, - args: &[ - 0x44, - 0x44, - ] - }), - Box::new(CustomCommand { - address: 0xE5, - args: &[ - 0x0D, - 0xD4, - 0x28, - 0x8C, - 0x0F, - 0xD6, - 0x28, - 0x8C, - 0x09, - 0xD0, - 0x28, - 0x8C, - 0x0B, - 0xD2, - 0x28, - 0x8C, - ] - }), - Box::new(CustomCommand { - address: 0xE6, - args: &[ - 0x00, - 0x00, - 0x33, - 0x33, - ] - }), - Box::new(CustomCommand { - address: 0xE7, - args: &[ - 0x44, - 0x44, - ] - }), - Box::new(CustomCommand { - address: 0xE8, - args: &[ - 0x0E, - 0xD5, - 0x28, - 0x8C, - 0x10, - 0xD7, - 0x28, - 0x8C, - 0x0A, - 0xD1, - 0x28, - 0x8C, - 0x0C, - 0xD3, - 0x28, - 0x8C, - ] - }), - Box::new(CustomCommand { - address: 0xEB, - args: &[ - 0x00, - 0x01, - 0xE4, - 0xE4, - 0x44, - 0x00, - ] - }), - Box::new(CustomCommand { - address: 0xED, - args: &[ - 0xF3, - 0xC1, - 0xBA, - 0x0F, - 0x66, - 0x77, - 0x44, - 0x55, - 0x55, - 0x44, - 0x77, - 0x66, - 0xF0, - 0xAB, - 0x1C, - 0x3F, - ] - }), - Box::new(CustomCommand { - address: 0xEF, - args: &[ - 0x10, - 0x0D, - 0x04, - 0x08, - 0x3F, - 0x1F, - ] - }), - Box::new(CmdCn2bkxsel( - CmdCn2bkxselArg0::new(), - CmdCn2bkxselArg1::new(), - CmdCn2bkxselArg2::new(), - CmdCn2bkxselArg3::new(), - CmdCn2bkxselArg4::new().with_bksel(0x3).with_cn2(true), - )), - Box::new(CustomCommand { - address: 0xE8, - args: &[ - 0x00, - 0x0E, - ], - }), - Box::new(CmdSlpout()), - ], 120), - (vec![ - Box::new(CustomCommand { - address: 0xE8, - args: &[ - 0x00, - 0x0C, - ], - }), - ], 10), - (vec![ - Box::new(CustomCommand { - address: 0xE8, - args: &[ - 0x40, - 0x00, - ], - }), - Box::new(CmdCn2bkxsel( - CmdCn2bkxselArg0::new(), - CmdCn2bkxselArg1::new(), - CmdCn2bkxselArg2::new(), - CmdCn2bkxselArg3::new(), - CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(false), - )), - Box::new(CmdMadctl( - CmdMadctlArg0::new().with_bgr(false).with_ml(false), - )), - Box::new(CmdColmod( - CmdColmodArg0::new().with_vipf(6) // 18-bit pixel - )), - Box::new(CmdDispon()), - ], 20), - // (vec![ - // Box::new(CmdCn2bkxsel( - // CmdCn2bkxselArg0::new(), - // CmdCn2bkxselArg1::new(), - // CmdCn2bkxselArg2::new(), - // CmdCn2bkxselArg3::new(), - // CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(true), - // )), - // Box::new(CmdPorctrl( - // CmdPorctrlArg0::new().with_vbp(0xFF), - // CmdPorctrlArg1::new().with_vfp(0x0), - // )), - // // Box::new(CmdRgbctrl( - // // CmdRgbctrlArg0::new() - // // .with_ep(false) - // // .with_dp(false) - // // .with_hsp(false) - // // .with_vsp(false) - // // .with_de_hv(true), - // // CmdRgbctrlArg1::new() - // // .with_hbp_hvrgb(16), - // // CmdRgbctrlArg2::new() - // // .with_vbp_hvrgb(8), - // // )), - // Box::new(CmdCn2bkxsel( - // CmdCn2bkxselArg0::new(), - // CmdCn2bkxselArg1::new(), - // CmdCn2bkxselArg2::new(), - // CmdCn2bkxselArg3::new(), - // CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(false), - // )), - // ], 20), - ]; +pub enum InitSequenceAction { + // TODO: Each command takes up 17 bytes. Consider storing compressed. + Command(ArrayCommand<16>), + SleepMs(u64), } + +macro_rules! make_init_action { + (command: $command:expr$(,)?) => { + InitSequenceAction::Command({ + let command = $command; + let args_slice = command.args_slice(); + let mut args_array = [0; _]; + let mut args_len = 0; + while args_len < args_slice.len() { + args_array[args_len] = args_slice[args_len]; + args_len += 1; + } + ArrayCommand { + address: command.address_const(), + args: match ArrayVec::try_from_array_len(args_array, args_len) { + Ok(args) => args, + Err(_) => panic!("too many command args"), + }, + } + }) + }; + + (sleep_ms: $expr:expr) => { + InitSequenceAction::SleepMs($expr) + }; +} + +macro_rules! make_init_sequence { + ($({ $($tt:tt)* }),*$(,)?) => { + [ + $( make_init_action!($($tt)*) ),* + ] + }; +} + +pub const INIT_SEQUENCE_COMMANDS: [InitSequenceAction; 46] = make_init_sequence! [ + { command: CmdCn2bkxsel( + CmdCn2bkxselArg0::new(), + CmdCn2bkxselArg1::new(), + CmdCn2bkxselArg2::new(), + CmdCn2bkxselArg3::new(), + CmdCn2bkxselArg4::new().with_bksel(0x3).with_cn2(true), + ) }, + { command: CustomCommand { + address: 0xEF, + args: &[0x08], + } }, + { command: CmdCn2bkxsel( + CmdCn2bkxselArg0::new(), + CmdCn2bkxselArg1::new(), + CmdCn2bkxselArg2::new(), + CmdCn2bkxselArg3::new(), + CmdCn2bkxselArg4::new().with_bksel(0x0).with_cn2(true), + ) }, + { command: CmdLneset( + CmdLnesetArg0::new().with_bar(119).with_lde_en(false), + CmdLnesetArg1::new().with_line_delta(0), + ) }, + { command: CmdPorctrl( + CmdPorctrlArg0::new().with_vbp(17), + CmdPorctrlArg1::new().with_vfp(12), + ) }, + { command: CmdInvsel( + CmdInvselArg0::new().with_nlinv(0b111), + CmdInvselArg1::new().with_rtni(2), + ) }, + { command: CustomCommand { + address: 0xCC, + args: &[0x30], + } }, + { command: CmdPvgamctrl( + CmdPvgamctrlArg0::new().with_vc0p(6).with_aj0p(0), + CmdPvgamctrlArg1::new().with_vc4p(15).with_aj1p(3), + CmdPvgamctrlArg2::new().with_vc8p(14).with_aj2p(0), + CmdPvgamctrlArg3::new().with_vc16p(12), + CmdPvgamctrlArg4::new().with_vc24p(15).with_aj3p(0), + CmdPvgamctrlArg5::new().with_vc52p(3), + CmdPvgamctrlArg6::new().with_vc80p(0), + CmdPvgamctrlArg7::new().with_vc108p(10), + CmdPvgamctrlArg8::new().with_vc147p(7), + CmdPvgamctrlArg9::new().with_vc175p(27), + CmdPvgamctrlArg10::new().with_vc203p(3), + CmdPvgamctrlArg11::new().with_vc231p(18).with_aj4p(0), + CmdPvgamctrlArg12::new().with_vc239p(16), + CmdPvgamctrlArg13::new().with_vc247p(37).with_aj5p(0), + CmdPvgamctrlArg14::new().with_vc251p(54).with_aj6p(0), + CmdPvgamctrlArg15::new().with_vc255p(30).with_aj7p(0), + ) }, + { command: CmdNvgamctrl( + CmdNvgamctrlArg0::new().with_vc0n(12).with_aj0n(0), + CmdNvgamctrlArg1::new().with_vc4n(14).with_aj1n(3), + CmdNvgamctrlArg2::new().with_vc8n(18).with_aj2n(0), + CmdNvgamctrlArg3::new().with_vc16n(12), + CmdNvgamctrlArg4::new().with_vc24n(14).with_aj3n(0), + CmdNvgamctrlArg5::new().with_vc52n(6), + CmdNvgamctrlArg6::new().with_vc80n(3), + CmdNvgamctrlArg7::new().with_vc108n(6), + CmdNvgamctrlArg8::new().with_vc147n(8), + CmdNvgamctrlArg9::new().with_vc175n(35), + CmdNvgamctrlArg10::new().with_vc203n(6), + CmdNvgamctrlArg11::new().with_vc231n(18).with_aj4n(0), + CmdNvgamctrlArg12::new().with_vc239n(16), + CmdNvgamctrlArg13::new().with_vc247n(48).with_aj5n(0), + CmdNvgamctrlArg14::new().with_vc251n(47).with_aj6n(0), + CmdNvgamctrlArg15::new().with_vc255n(31).with_aj7n(0), + ) }, + { command: CmdCn2bkxsel( + CmdCn2bkxselArg0::new(), + CmdCn2bkxselArg1::new(), + CmdCn2bkxselArg2::new(), + CmdCn2bkxselArg3::new(), + CmdCn2bkxselArg4::new().with_bksel(0x1).with_cn2(true), + ) }, + { command: CmdVrhs( + CmdVrhsArg0::new().with_vrha(115), + ) }, + { command: CmdVcoms( + CmdVcomsArg0::new().with_vcom(124), + ) }, + { command: CmdVghss( + // The first bit is set to 1 in the original init code, but not here. + CmdVghssArg0::new().with_vghss(0x3), // 13 V + ) }, + { command: CmdTescmd( + CmdTescmdArg0::new(), + ) }, + { command: CmdVgls( + CmdVglsArg0::new().with_vgls(0x9) // -10.17 V + ) }, + { command: CmdPwctrl1( + CmdPwctrl1Arg0::new() + .with_apos(0x3) // Max + .with_apis(0x1) // Min + .with_ap(0x2) // Middle + ) }, + { command: CmdPwctrl2( + CmdPwctrl2Arg0::new() + .with_avcl(0x3) // -5 V + .with_avdd(0x3) // 6.8 V + ) }, + { command: CmdPwctrl3( + CmdPwctrl3Arg0::new() + .with_svno_pum(0) // Cell setting 4 + .with_svpo_pum(0x1) // Cell setting 5 + ) }, + { command: CmdPclks2( + CmdPclks2Arg0::new().with_sbstcks(0x3) + ) }, + { command: CmdPdr1( + CmdPdr1Arg0::new().with_t2d(8) // 1.6 us + ) }, + { command: CmdPdr2( + CmdPdr2Arg0::new().with_t3d(8) // 6.4 us + ) }, + { command: CmdMipiset1( + CmdMipiset1Arg0::new().with_err_sel(0).with_eotp_en(true), + ) }, + { command: CustomCommand { + address: 0xE0, + args: &[ + 0x00, + 0x00, + 0x02, + 0x00, + 0x00, + 0x0C, + ] + } }, + { command: CustomCommand { + address: 0xE1, + args: &[ + 0x05, + 0x96, + 0x07, + 0x96, + 0x06, + 0x96, + 0x08, + 0x96, + 0x00, + 0x44, + 0x44, + ] + } }, + { command: CustomCommand { + address: 0xE2, + args: &[ + 0x00, + 0x00, + 0x03, + 0x03, + 0x00, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + ] + } }, + { command: CustomCommand { + address: 0xE3, + args: &[ + 0x00, + 0x00, + 0x33, + 0x33, + ] + } }, + { command: CustomCommand { + address: 0xE4, + args: &[ + 0x44, + 0x44, + ] + } }, + { command: CustomCommand { + address: 0xE5, + args: &[ + 0x0D, + 0xD4, + 0x28, + 0x8C, + 0x0F, + 0xD6, + 0x28, + 0x8C, + 0x09, + 0xD0, + 0x28, + 0x8C, + 0x0B, + 0xD2, + 0x28, + 0x8C, + ] + } }, + { command: CustomCommand { + address: 0xE6, + args: &[ + 0x00, + 0x00, + 0x33, + 0x33, + ] + } }, + { command: CustomCommand { + address: 0xE7, + args: &[ + 0x44, + 0x44, + ] + } }, + { command: CustomCommand { + address: 0xE8, + args: &[ + 0x0E, + 0xD5, + 0x28, + 0x8C, + 0x10, + 0xD7, + 0x28, + 0x8C, + 0x0A, + 0xD1, + 0x28, + 0x8C, + 0x0C, + 0xD3, + 0x28, + 0x8C, + ] + } }, + { command: CustomCommand { + address: 0xEB, + args: &[ + 0x00, + 0x01, + 0xE4, + 0xE4, + 0x44, + 0x00, + ] + } }, + { command: CustomCommand { + address: 0xED, + args: &[ + 0xF3, + 0xC1, + 0xBA, + 0x0F, + 0x66, + 0x77, + 0x44, + 0x55, + 0x55, + 0x44, + 0x77, + 0x66, + 0xF0, + 0xAB, + 0x1C, + 0x3F, + ] + } }, + { command: CustomCommand { + address: 0xEF, + args: &[ + 0x10, + 0x0D, + 0x04, + 0x08, + 0x3F, + 0x1F, + ] + } }, + { command: CmdCn2bkxsel( + CmdCn2bkxselArg0::new(), + CmdCn2bkxselArg1::new(), + CmdCn2bkxselArg2::new(), + CmdCn2bkxselArg3::new(), + CmdCn2bkxselArg4::new().with_bksel(0x3).with_cn2(true), + ) }, + { command: CustomCommand { + address: 0xE8, + args: &[ + 0x00, + 0x0E, + ], + } }, + { command: CmdSlpout() }, + { sleep_ms: 120 }, + { command: CustomCommand { + address: 0xE8, + args: &[ + 0x00, + 0x0C, + ], + } }, + { sleep_ms: 10 }, + { command: CustomCommand { + address: 0xE8, + args: &[ + 0x40, + 0x00, + ], + } }, + { command: CmdCn2bkxsel( + CmdCn2bkxselArg0::new(), + CmdCn2bkxselArg1::new(), + CmdCn2bkxselArg2::new(), + CmdCn2bkxselArg3::new(), + CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(false), + ) }, + { command: CmdMadctl( + CmdMadctlArg0::new().with_bgr(false).with_ml(false), + ) }, + { command: CmdColmod( + CmdColmodArg0::new().with_vipf(6) // 18-bit pixel + ) }, + { command: CmdDispon() }, + { sleep_ms: 20 }, + // { command: CmdCn2bkxsel( + // CmdCn2bkxselArg0::new(), + // CmdCn2bkxselArg1::new(), + // CmdCn2bkxselArg2::new(), + // CmdCn2bkxselArg3::new(), + // CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(true), + // ) }, + // { command: CmdPorctrl( + // CmdPorctrlArg0::new().with_vbp(0xFF), + // CmdPorctrlArg1::new().with_vfp(0x0), + // ) }, + // // { command: CmdRgbctrl( + // // CmdRgbctrlArg0::new() + // // .with_ep(false) + // // .with_dp(false) + // // .with_hsp(false) + // // .with_vsp(false) + // // .with_de_hv(true), + // // CmdRgbctrlArg1::new() + // // .with_hbp_hvrgb(16), + // // CmdRgbctrlArg2::new() + // // .with_vbp_hvrgb(8), + // // ) }, + // { command: CmdCn2bkxsel( + // CmdCn2bkxselArg0::new(), + // CmdCn2bkxselArg1::new(), + // CmdCn2bkxselArg2::new(), + // CmdCn2bkxselArg3::new(), + // CmdCn2bkxselArg4::new().with_bksel(0).with_cn2(false), + // ) }, + // { sleep_ms: 20 }, +]; diff --git a/firmware/acid-firmware/src/peripherals/st7701s/mod.rs b/firmware/acid-firmware/src/peripherals/st7701s/mod.rs index 12a46f3..de55fda 100644 --- a/firmware/acid-firmware/src/peripherals/st7701s/mod.rs +++ b/firmware/acid-firmware/src/peripherals/st7701s/mod.rs @@ -12,7 +12,7 @@ use esp_hal::{ use log::debug; use ouroboros::self_referencing; -use crate::peripherals::st7701s::commands::Command; +use crate::peripherals::st7701s::{commands::Command, init_sequence::InitSequenceAction}; mod commands; mod init_sequence; @@ -43,19 +43,22 @@ impl<'d> St7701sController<'d> { pub async fn send_init_sequence(&mut self) { debug!("Writing ST7701S init sequence."); - for (subsequence, delay_ms) in &*init_sequence::INIT_SEQUENCE_COMMANDS { - for command in subsequence { - spi::spi_write( - command.address(), - command.args_iter().copied(), - &mut self.mosi, - &mut self.sck, - &mut self.cs, - ) - .await; + for action in &init_sequence::INIT_SEQUENCE_COMMANDS { + match action { + InitSequenceAction::Command(command) => { + spi::spi_write( + command.address(), + command.args_iter().copied(), + &mut self.mosi, + &mut self.sck, + &mut self.cs, + ) + .await; + } + InitSequenceAction::SleepMs(delay_ms) => { + Timer::after_millis(*delay_ms).await; + } } - - Timer::after_millis(*delay_ms).await; } }