1use crate::{mipi_dsi::MipiDsi, peripherals::MIPI_DSI_HOST};
4
5const DT_DCS_SHORT_WRITE_0: u8 = 0x05;
7const DT_DCS_SHORT_WRITE_1: u8 = 0x15;
8const DT_DCS_LONG_WRITE: u8 = 0x39;
9const DT_DCS_READ_0: u8 = 0x06;
10const DT_SET_MAX_RETURN_PKT: u8 = 0x37;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15pub enum Error {
16 PayloadTooLarge,
18}
19
20pub struct DsiDbi<'bus, 'd> {
25 _bus: &'bus mut MipiDsi<'d>,
26 virtual_channel: u8,
27}
28
29impl<'bus, 'd> DsiDbi<'bus, 'd> {
30 pub(crate) fn new(bus: &'bus mut MipiDsi<'d>, virtual_channel: u8) -> Self {
31 let h = MIPI_DSI_HOST::regs();
32
33 h.cmd_mode_cfg().modify(|_, w| {
35 w.tear_fx_en().clear_bit();
36 w.ack_rqst_en().set_bit();
37 w.gen_sw_0p_tx().set_bit();
38 w.gen_sw_1p_tx().set_bit();
39 w.gen_sw_2p_tx().set_bit();
40 w.gen_sr_0p_tx().set_bit();
41 w.gen_sr_1p_tx().set_bit();
42 w.gen_sr_2p_tx().set_bit();
43 w.gen_lw_tx().set_bit();
44 w.dcs_sw_0p_tx().set_bit();
45 w.dcs_sw_1p_tx().set_bit();
46 w.dcs_sr_0p_tx().set_bit();
47 w.dcs_lw_tx().set_bit();
48 w.max_rd_pkt_size().set_bit()
49 });
50
51 Self {
52 _bus: bus,
53 virtual_channel,
54 }
55 }
56
57 pub fn virtual_channel(&self) -> u8 {
59 self.virtual_channel
60 }
61
62 pub fn write_cmd(&mut self, cmd: u8, params: &[u8]) -> Result<(), Error> {
67 let h = MIPI_DSI_HOST::regs();
68 let vc = self.virtual_channel;
69 let payload_size = 1 + params.len(); if payload_size > u16::MAX as usize {
72 return Err(Error::PayloadTooLarge);
73 }
74
75 if payload_size > 2 {
76 let merged = params.len().min(3);
79 let mut word: u32 = cmd as u32;
80 for (i, &b) in params[..merged].iter().enumerate() {
81 word |= (b as u32) << (8 * (i + 1));
82 }
83 while h.cmd_pkt_status().read().gen_pld_w_full().bit_is_set() {}
84 h.gen_pld_data().write(|w| unsafe { w.bits(word) });
85
86 let rest = ¶ms[merged..];
87 let (chunks, tail) = rest.as_chunks::<4>();
88 for chunk in chunks {
89 let w32 = u32::from_le_bytes(*chunk);
90 while h.cmd_pkt_status().read().gen_pld_w_full().bit_is_set() {}
91 h.gen_pld_data().write(|w| unsafe { w.bits(w32) });
92 }
93 if !tail.is_empty() {
94 let mut w32: u32 = 0;
95 for (i, &b) in tail.iter().enumerate() {
96 w32 |= (b as u32) << (8 * i);
97 }
98 while h.cmd_pkt_status().read().gen_pld_w_full().bit_is_set() {}
99 h.gen_pld_data().write(|w| unsafe { w.bits(w32) });
100 }
101
102 let wc = payload_size as u16;
103 while h.cmd_pkt_status().read().gen_cmd_full().bit_is_set() {}
104 h.gen_hdr().write(|w| unsafe {
105 w.gen_vc().bits(vc);
106 w.gen_dt().bits(DT_DCS_LONG_WRITE);
107 w.gen_wc_lsbyte().bits((wc & 0xFF) as u8);
108 w.gen_wc_msbyte().bits((wc >> 8) as u8)
109 });
110 } else if payload_size == 2 {
111 while h.cmd_pkt_status().read().gen_cmd_full().bit_is_set() {}
113 h.gen_hdr().write(|w| unsafe {
114 w.gen_vc().bits(vc);
115 w.gen_dt().bits(DT_DCS_SHORT_WRITE_1);
116 w.gen_wc_lsbyte().bits(cmd);
117 w.gen_wc_msbyte().bits(params[0])
118 });
119 } else {
120 while h.cmd_pkt_status().read().gen_cmd_full().bit_is_set() {}
122 h.gen_hdr().write(|w| unsafe {
123 w.gen_vc().bits(vc);
124 w.gen_dt().bits(DT_DCS_SHORT_WRITE_0);
125 w.gen_wc_lsbyte().bits(cmd);
126 w.gen_wc_msbyte().bits(0)
127 });
128 }
129
130 Ok(())
131 }
132
133 pub fn read_cmd(&mut self, cmd: u8, out: &mut [u8]) -> Result<usize, Error> {
137 let h = MIPI_DSI_HOST::regs();
138 let vc = self.virtual_channel;
139
140 if out.len() > u16::MAX as usize {
141 return Err(Error::PayloadTooLarge);
142 }
143
144 let max_ret = out.len() as u16;
146 while h.cmd_pkt_status().read().gen_cmd_full().bit_is_set() {}
147 h.gen_hdr().write(|w| unsafe {
148 w.gen_vc().bits(vc);
149 w.gen_dt().bits(DT_SET_MAX_RETURN_PKT);
150 w.gen_wc_lsbyte().bits((max_ret & 0xFF) as u8);
151 w.gen_wc_msbyte().bits((max_ret >> 8) as u8)
152 });
153
154 h.mode_cfg().modify(|_, w| w.cmd_video_mode().set_bit());
156
157 h.pckhdl_cfg().modify(|_, w| w.bta_en().set_bit());
159 h.gen_vcid().modify(|_, w| unsafe { w.rx().bits(vc) });
160
161 while h.cmd_pkt_status().read().gen_cmd_full().bit_is_set() {}
163 h.gen_hdr().write(|w| unsafe {
164 w.gen_vc().bits(vc);
165 w.gen_dt().bits(DT_DCS_READ_0);
166 w.gen_wc_lsbyte().bits(cmd);
167 w.gen_wc_msbyte().bits(0)
168 });
169
170 while h.cmd_pkt_status().read().gen_rd_cmd_busy().bit_is_set() {}
172
173 while h.cmd_pkt_status().read().gen_pld_r_empty().bit_is_set() {}
175 let mut count = 0usize;
176 while !h.cmd_pkt_status().read().gen_pld_r_empty().bit_is_set() {
177 let word = h.gen_pld_data().read().bits();
178 for i in 0..4 {
179 if count < out.len() {
180 out[count] = ((word >> (8 * i)) & 0xFF) as u8;
181 count += 1;
182 }
183 }
184 }
185
186 Ok(count)
187 }
188}