diff options
| -rw-r--r-- | embassy-stm32/src/dsihost.rs | 49 |
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) { |
