Skip to main content

st7305_lcd/cmd/nvm/
program.rs

1//! Commands that program the NVM (MTP) of the panel or change its identity.
2//!
3//! Only available with the `nvm-program` feature. The ST7305 datasheet v0.2
4//! (§6.5, §8.2.26–8.2.29, §9) requires an external programming supply VPP of
5//! about 7.5 V (> 8 mA) and the EXTB pin pulled to VDGND; without them the
6//! commands have no effect.
7
8use crate::{command::WriteCommand, instr::Instr};
9
10/// `NVMCTRL2` (§8.2.27): NVM register address and data to program.
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub struct NvmProgramSetting {
13    /// `PA[5:0]`: register address
14    pa: u8,
15    /// `PIN[7:0]`: data
16    pin: u8,
17}
18
19impl NvmProgramSetting {
20    /// Register default: address 0, data 0.
21    pub const DEFAULT: Self = Self { pa: 0, pin: 0 };
22
23    /// Programs `pin` at the NVM address `pa` (6 bits).
24    ///
25    /// # Panics
26    ///
27    /// If `pa > 63` (at compile time in a `const`).
28    pub const fn new(pa: u8, pin: u8) -> Self {
29        assert!(pa >> 6 == 0, "PA out of range");
30        Self { pa, pin }
31    }
32
33    const fn bytes(&self) -> [u8; 2] {
34        [self.pa, self.pin]
35    }
36}
37
38impl Default for NvmProgramSetting {
39    fn default() -> Self {
40        Self::DEFAULT
41    }
42}
43
44impl WriteCommand for NvmProgramSetting {
45    const OPCODE: Instr = Instr::NVMCTRL2;
46    type Params = [u8; 2];
47    fn params(&self) -> Self::Params {
48        self.bytes()
49    }
50}
51
52const _: () = assert!(matches!(NvmProgramSetting::DEFAULT.bytes(), [0x00, 0x00]));
53
54/// `NVMPROM` (§8.2.29): enables NVM program mode (sends the key `29h A5h`).
55#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56pub struct NvmProgramEnable;
57
58impl NvmProgramEnable {
59    const fn bytes(&self) -> [u8; 2] {
60        [0x29, 0xA5]
61    }
62}
63
64impl WriteCommand for NvmProgramEnable {
65    const OPCODE: Instr = Instr::NVMPROM;
66    type Params = [u8; 2];
67    fn params(&self) -> Self::Params {
68        self.bytes()
69    }
70}
71
72const _: () = assert!(matches!(NvmProgramEnable.bytes(), [0x29, 0xA5]));
73
74/// `ID1SET` (§8.2.17): the ID1 code, read back with `RDID1`.
75#[derive(Clone, Copy, Debug, PartialEq, Eq)]
76pub struct Id1Setting {
77    id: u8,
78}
79
80impl Id1Setting {
81    /// Register default `0x00`.
82    pub const DEFAULT: Self = Self { id: 0 };
83
84    /// ID1 = `id`.
85    pub const fn new(id: u8) -> Self {
86        Self { id }
87    }
88}
89
90impl Default for Id1Setting {
91    fn default() -> Self {
92        Self::DEFAULT
93    }
94}
95
96impl WriteCommand for Id1Setting {
97    const OPCODE: Instr = Instr::ID1SET;
98    type Params = [u8; 1];
99    fn params(&self) -> Self::Params {
100        [self.id]
101    }
102}
103
104/// `ID2SET` (§8.2.18): the ID2 code, read back with `RDID2`.
105#[derive(Clone, Copy, Debug, PartialEq, Eq)]
106pub struct Id2Setting {
107    id: u8,
108}
109
110impl Id2Setting {
111    /// Register default `0x00`.
112    pub const DEFAULT: Self = Self { id: 0 };
113
114    /// ID2 = `id`.
115    pub const fn new(id: u8) -> Self {
116        Self { id }
117    }
118}
119
120impl Default for Id2Setting {
121    fn default() -> Self {
122        Self::DEFAULT
123    }
124}
125
126impl WriteCommand for Id2Setting {
127    const OPCODE: Instr = Instr::ID2SET;
128    type Params = [u8; 1];
129    fn params(&self) -> Self::Params {
130        [self.id]
131    }
132}
133
134/// `ID3SET` (§8.2.19): the ID3 code, read back with `RDID3`.
135#[derive(Clone, Copy, Debug, PartialEq, Eq)]
136pub struct Id3Setting {
137    id: u8,
138}
139
140impl Id3Setting {
141    /// Register default `0x00`.
142    pub const DEFAULT: Self = Self { id: 0 };
143
144    /// ID3 = `id`.
145    pub const fn new(id: u8) -> Self {
146        Self { id }
147    }
148}
149
150impl Default for Id3Setting {
151    fn default() -> Self {
152        Self::DEFAULT
153    }
154}
155
156impl WriteCommand for Id3Setting {
157    const OPCODE: Instr = Instr::ID3SET;
158    type Params = [u8; 1];
159    fn params(&self) -> Self::Params {
160        [self.id]
161    }
162}
163
164/// `EXTBCTRL` (§8.2.25): internal level of the EXTB signal.
165#[derive(Clone, Copy, Debug, PartialEq, Eq)]
166pub struct ExtbControl {
167    extb_ctrl: ExtbCtrl,
168}
169
170impl ExtbControl {
171    /// Register default `0x5A`: EXTB high.
172    pub const DEFAULT: Self = Self {
173        extb_ctrl: ExtbCtrl::Vdd,
174    };
175
176    /// `EXTB_CTRL[7:0]` = `extb_ctrl`.
177    pub const fn new(extb_ctrl: ExtbCtrl) -> Self {
178        Self { extb_ctrl }
179    }
180
181    const fn bytes(&self) -> [u8; 1] {
182        [self.extb_ctrl as u8]
183    }
184}
185
186impl Default for ExtbControl {
187    fn default() -> Self {
188        Self::DEFAULT
189    }
190}
191
192impl WriteCommand for ExtbControl {
193    const OPCODE: Instr = Instr::EXTBCTRL;
194    type Params = [u8; 1];
195    fn params(&self) -> Self::Params {
196        self.bytes()
197    }
198}
199
200/// `EXTB_CTRL[7:0]`: EXTB level.
201#[derive(Clone, Copy, Debug, PartialEq, Eq)]
202pub enum ExtbCtrl {
203    /// EXTB high (VDD)
204    Vdd = 0x5A,
205    /// EXTB low (VSS)
206    Vss = 0xA5,
207}
208
209const _: () = assert!(matches!(ExtbControl::DEFAULT.bytes(), [0x5A]));