aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoël Schulz-Ansres <[email protected]>2024-05-14 12:16:43 +0200
committerJoël Schulz-Ansres <[email protected]>2024-05-14 12:16:43 +0200
commit94cf606892fe01e377a5b38965d02f5cb9ba8d55 (patch)
tree54f1cff12e871ab7b9f7f8cff868588e2f9ac8f5
parent9005d26fca57cce65b48f6ec823238aea7e36082 (diff)
Improve write_cmd parameters
-rw-r--r--embassy-stm32/src/dsihost.rs49
1 files changed, 34 insertions, 15 deletions
diff --git a/embassy-stm32/src/dsihost.rs b/embassy-stm32/src/dsihost.rs
index 110c28b92..787677082 100644
--- a/embassy-stm32/src/dsihost.rs
+++ b/embassy-stm32/src/dsihost.rs
@@ -123,7 +123,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
123 } 123 }
124 124
125 /// DCS or Generic short/long write command 125 /// DCS or Generic short/long write command
126 pub fn write_cmd(&mut self, channel_id: u8, params: &[u8]) { 126 pub fn write_cmd(&mut self, channel_id: u8, params: &[u8]) -> Result<(), Error> {
127 if params.len() <= 2 { 127 if params.len() <= 2 {
128 self.short_write(channel_id, PacketType::DcsShortPktWriteP1, params[0], params[1]) 128 self.short_write(channel_id, PacketType::DcsShortPktWriteP1, params[0], params[1])
129 } else { 129 } else {
@@ -135,18 +135,26 @@ impl<'d, T: Instance> DsiHost<'d, T> {
135 } 135 }
136 } 136 }
137 137
138 fn short_write(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) { 138 fn short_write(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) -> Result<(), Error> {
139 #[cfg(feature = "defmt")] 139 #[cfg(feature = "defmt")]
140 defmt::debug!("short_write: BEGIN wait for command fifo empty"); 140 defmt::debug!("short_write: BEGIN wait for command fifo empty");
141 141
142 // Wait for Command FIFO empty 142 // Wait for Command FIFO empty
143 self.wait_command_fifo_empty().unwrap(); 143 self.wait_command_fifo_empty()?;
144 #[cfg(feature = "defmt")] 144 #[cfg(feature = "defmt")]
145 defmt::debug!("short_write: END wait for command fifo empty"); 145 defmt::debug!("short_write: END wait for command fifo empty");
146 146
147 // Configure the packet to send a short DCS command with 0 or 1 parameters 147 // Configure the packet to send a short DCS command with 0 or 1 parameters
148 // Update the DSI packet header with new information 148 // Update the DSI packet header with new information
149 self.config_packet_header(channel_id, packet_type, param1, param2); 149 self.config_packet_header(channel_id, packet_type, param1, param2);
150
151 self.wait_command_fifo_empty()?;
152
153 let status = T::regs().isr1().read().0;
154 if status != 0 {
155 error!("ISR1 after short_write(): {:b}", status);
156 }
157 Ok(())
150 } 158 }
151 159
152 fn config_packet_header(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) { 160 fn config_packet_header(&mut self, channel_id: u8, packet_type: PacketType, param1: u8, param2: u8) {
@@ -161,7 +169,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
161 /// Write long DCS or long Generic command. 169 /// Write long DCS or long Generic command.
162 /// 170 ///
163 /// `params` is expected to contain at least 3 elements. Use [`short_write`] for 2 or less. 171 /// `params` is expected to contain at least 3 elements. Use [`short_write`] for 2 or less.
164 fn long_write(&mut self, channel_id: u8, packet_type: PacketType, params: &[u8]) { 172 fn long_write(&mut self, channel_id: u8, packet_type: PacketType, params: &[u8]) -> Result<(), Error> {
165 // Must be a long packet if we do the long write, obviously. 173 // Must be a long packet if we do the long write, obviously.
166 assert!(matches!( 174 assert!(matches!(
167 packet_type, 175 packet_type,
@@ -174,7 +182,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
174 #[cfg(feature = "defmt")] 182 #[cfg(feature = "defmt")]
175 defmt::debug!("long_write: BEGIN wait for command fifo empty"); 183 defmt::debug!("long_write: BEGIN wait for command fifo empty");
176 184
177 self.wait_command_fifo_empty().unwrap(); 185 self.wait_command_fifo_empty()?;
178 186
179 #[cfg(feature = "defmt")] 187 #[cfg(feature = "defmt")]
180 defmt::debug!("long_write: DONE wait for command fifo empty"); 188 defmt::debug!("long_write: DONE wait for command fifo empty");
@@ -198,8 +206,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
198 w.set_data1(dcs_code); 206 w.set_data1(dcs_code);
199 }); 207 });
200 208
201 // FIXME: This probably should return an error 209 self.wait_command_fifo_empty()?;
202 self.wait_command_fifo_empty().unwrap();
203 210
204 // These steps are only necessary if more than 1x 4 bytes need to go into the FIFO 211 // These steps are only necessary if more than 1x 4 bytes need to go into the FIFO
205 if data.len() >= 4 { 212 if data.len() >= 4 {
@@ -210,6 +217,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
210 217
211 // Keep filling the buffer with remaining data 218 // Keep filling the buffer with remaining data
212 for param in iter { 219 for param in iter {
220 self.wait_command_fifo_not_full()?;
213 T::regs().gpdr().write(|w| { 221 T::regs().gpdr().write(|w| {
214 w.set_data4(param[3]); 222 w.set_data4(param[3]);
215 w.set_data3(param[2]); 223 w.set_data3(param[2]);
@@ -222,6 +230,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
222 230
223 // If the remaining data was not devisible by 4 we get a remainder 231 // If the remaining data was not devisible by 4 we get a remainder
224 if remainder.len() >= 1 { 232 if remainder.len() >= 1 {
233 self.wait_command_fifo_not_full()?;
225 T::regs().gpdr().write(|w| { 234 T::regs().gpdr().write(|w| {
226 if let Some(x) = remainder.get(2) { 235 if let Some(x) = remainder.get(2) {
227 w.set_data3(*x); 236 w.set_data3(*x);
@@ -235,12 +244,20 @@ impl<'d, T: Instance> DsiHost<'d, T> {
235 } 244 }
236 } 245 }
237 // Configure the packet to send a long DCS command 246 // Configure the packet to send a long DCS command
238 T::regs().ghcr().write(|w| { 247 self.config_packet_header(
239 w.set_dt(packet_type.into()); 248 channel_id,
240 w.set_vcid(channel_id); 249 packet_type,
241 w.set_wclsb((params.len() & 0x00FF) as u8); 250 (params.len() & 0x00FF) as u8,
242 w.set_wcmsb((params.len() & 0xFF00 >> 8) as u8); 251 ((params.len() & 0xFF00) >> 8) as u8,
243 }); 252 );
253
254 self.wait_command_fifo_empty()?;
255
256 let status = T::regs().isr1().read().0;
257 if status != 0 {
258 error!("ISR1 after long_write(): {:b}", status);
259 }
260 Ok(())
244 } 261 }
245 262
246 /// Read DSI Register 263 /// Read DSI Register
@@ -273,9 +290,11 @@ impl<'d, T: Instance> DsiHost<'d, T> {
273 _ => return Err(Error::InvalidPacketType), 290 _ => return Err(Error::InvalidPacketType),
274 } 291 }
275 292
293 self.wait_read_not_busy()?;
294
276 // Obtain chunks of 32-bit so the entire FIFO data register can be read 295 // Obtain chunks of 32-bit so the entire FIFO data register can be read
277 for bytes in data.chunks_exact_mut(4) { 296 for bytes in data.chunks_exact_mut(4) {
278 self.wait_payload_read_fifo_not_empty().unwrap(); 297 self.wait_payload_read_fifo_not_empty()?;
279 298
280 // Only perform a single read on the entire register to avoid unintended side-effects 299 // Only perform a single read on the entire register to avoid unintended side-effects
281 let gpdr = T::regs().gpdr().read(); 300 let gpdr = T::regs().gpdr().read();
@@ -288,7 +307,7 @@ impl<'d, T: Instance> DsiHost<'d, T> {
288 // Collect the remaining chunks and read the corresponding number of bytes from the FIFO 307 // Collect the remaining chunks and read the corresponding number of bytes from the FIFO
289 let remainder = data.chunks_exact_mut(4).into_remainder(); 308 let remainder = data.chunks_exact_mut(4).into_remainder();
290 if !remainder.is_empty() { 309 if !remainder.is_empty() {
291 self.wait_payload_read_fifo_not_empty().unwrap(); 310 self.wait_payload_read_fifo_not_empty()?;
292 // Only perform a single read on the entire register to avoid unintended side-effects 311 // Only perform a single read on the entire register to avoid unintended side-effects
293 let gpdr = T::regs().gpdr().read(); 312 let gpdr = T::regs().gpdr().read();
294 if let Some(x) = remainder.get_mut(0) { 313 if let Some(x) = remainder.get_mut(0) {