diff options
| -rw-r--r-- | embassy-stm32/src/ucpd.rs | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index 071bfd1b1..64969beb8 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs | |||
| @@ -181,8 +181,8 @@ impl<'d, T: Instance> Ucpd<'d, T> { | |||
| 181 | r.tx_ordsetr().write(|w| w.set_txordset(0b10001_11000_11000_11000)); | 181 | r.tx_ordsetr().write(|w| w.set_txordset(0b10001_11000_11000_11000)); |
| 182 | 182 | ||
| 183 | r.cfgr1().modify(|w| { | 183 | r.cfgr1().modify(|w| { |
| 184 | // TODO: Currently only SOP messages are supported. | 184 | // TODO: Currently only hard reset and SOP messages can be received. |
| 185 | w.set_rxordseten(0x1); | 185 | w.set_rxordseten(0b1001); |
| 186 | 186 | ||
| 187 | // Enable DMA | 187 | // Enable DMA |
| 188 | w.set_txdmaen(true); | 188 | w.set_txdmaen(true); |
| @@ -195,6 +195,9 @@ impl<'d, T: Instance> Ucpd<'d, T> { | |||
| 195 | w.set_phyrxen(true); | 195 | w.set_phyrxen(true); |
| 196 | }); | 196 | }); |
| 197 | 197 | ||
| 198 | // Enable hard reset receive interrupt. | ||
| 199 | r.imr().modify(|w| w.set_rxhrstdetie(true)); | ||
| 200 | |||
| 198 | into_ref!(rx_dma, tx_dma); | 201 | into_ref!(rx_dma, tx_dma); |
| 199 | let rx_dma_req = rx_dma.request(); | 202 | let rx_dma_req = rx_dma.request(); |
| 200 | let tx_dma_req = tx_dma.request(); | 203 | let tx_dma_req = tx_dma.request(); |
| @@ -217,6 +220,9 @@ pub enum RxError { | |||
| 217 | 220 | ||
| 218 | /// Provided buffer was too small for the received message. | 221 | /// Provided buffer was too small for the received message. |
| 219 | Overrun, | 222 | Overrun, |
| 223 | |||
| 224 | /// Hard Reset received before or during reception. | ||
| 225 | HardReset, | ||
| 220 | } | 226 | } |
| 221 | 227 | ||
| 222 | /// Transmit Error. | 228 | /// Transmit Error. |
| @@ -225,6 +231,9 @@ pub enum RxError { | |||
| 225 | pub enum TxError { | 231 | pub enum TxError { |
| 226 | /// Concurrent receive in progress or excessive noise on the line. | 232 | /// Concurrent receive in progress or excessive noise on the line. |
| 227 | Discarded, | 233 | Discarded, |
| 234 | |||
| 235 | /// Hard Reset received before or during transmission. | ||
| 236 | HardReset, | ||
| 228 | } | 237 | } |
| 229 | 238 | ||
| 230 | /// Power Delivery (PD) PHY. | 239 | /// Power Delivery (PD) PHY. |
| @@ -252,7 +261,9 @@ impl<'d, T: Instance> PdPhy<'d, T> { | |||
| 252 | // Check if a message is already being received. If yes, wait until its | 261 | // Check if a message is already being received. If yes, wait until its |
| 253 | // done, ignore errors and try to receive the next message. | 262 | // done, ignore errors and try to receive the next message. |
| 254 | if r.sr().read().rxorddet() { | 263 | if r.sr().read().rxorddet() { |
| 255 | let _ = self.wait_rx_done().await; | 264 | if let Err(RxError::HardReset) = self.wait_rx_done().await { |
| 265 | return Err(RxError::HardReset); | ||
| 266 | } | ||
| 256 | r.rxdr().read(); // Clear the RX buffer. | 267 | r.rxdr().read(); // Clear the RX buffer. |
| 257 | } | 268 | } |
| 258 | 269 | ||
| @@ -290,7 +301,12 @@ impl<'d, T: Instance> PdPhy<'d, T> { | |||
| 290 | poll_fn(|cx| { | 301 | poll_fn(|cx| { |
| 291 | let r = T::REGS; | 302 | let r = T::REGS; |
| 292 | let sr = r.sr().read(); | 303 | let sr = r.sr().read(); |
| 293 | if sr.rxmsgend() { | 304 | if sr.rxhrstdet() { |
| 305 | // Clean and re-enable hard reset receive interrupt. | ||
| 306 | r.icr().write(|w| w.set_rxhrstdetcf(true)); | ||
| 307 | r.imr().modify(|w| w.set_rxhrstdetie(true)); | ||
| 308 | Poll::Ready(Err(RxError::HardReset)) | ||
| 309 | } else if sr.rxmsgend() { | ||
| 294 | let ret = if sr.rxovr() { | 310 | let ret = if sr.rxovr() { |
| 295 | Err(RxError::Overrun) | 311 | Err(RxError::Overrun) |
| 296 | } else if sr.rxerr() { | 312 | } else if sr.rxerr() { |
| @@ -326,7 +342,9 @@ impl<'d, T: Instance> PdPhy<'d, T> { | |||
| 326 | // might still be running because there is no way to abort an ongoing | 342 | // might still be running because there is no way to abort an ongoing |
| 327 | // message transmission. Wait for it to finish but ignore errors. | 343 | // message transmission. Wait for it to finish but ignore errors. |
| 328 | if r.cr().read().txsend() { | 344 | if r.cr().read().txsend() { |
| 329 | let _ = self.wait_tx_done().await; | 345 | if let Err(TxError::HardReset) = self.wait_tx_done().await { |
| 346 | return Err(TxError::HardReset); | ||
| 347 | } | ||
| 330 | } | 348 | } |
| 331 | 349 | ||
| 332 | // Clear the TX interrupt flags. | 350 | // Clear the TX interrupt flags. |
| @@ -360,9 +378,15 @@ impl<'d, T: Instance> PdPhy<'d, T> { | |||
| 360 | let _on_drop = OnDrop::new(|| self.enable_tx_interrupts(false)); | 378 | let _on_drop = OnDrop::new(|| self.enable_tx_interrupts(false)); |
| 361 | poll_fn(|cx| { | 379 | poll_fn(|cx| { |
| 362 | let r = T::REGS; | 380 | let r = T::REGS; |
| 363 | if r.sr().read().txmsgdisc() { | 381 | let sr = r.sr().read(); |
| 382 | if sr.rxhrstdet() { | ||
| 383 | // Clean and re-enable hard reset receive interrupt. | ||
| 384 | r.icr().write(|w| w.set_rxhrstdetcf(true)); | ||
| 385 | r.imr().modify(|w| w.set_rxhrstdetie(true)); | ||
| 386 | Poll::Ready(Err(TxError::HardReset)) | ||
| 387 | } else if sr.txmsgdisc() { | ||
| 364 | Poll::Ready(Err(TxError::Discarded)) | 388 | Poll::Ready(Err(TxError::Discarded)) |
| 365 | } else if r.sr().read().txmsgsent() { | 389 | } else if sr.txmsgsent() { |
| 366 | Poll::Ready(Ok(())) | 390 | Poll::Ready(Ok(())) |
| 367 | } else { | 391 | } else { |
| 368 | T::waker().register(cx.waker()); | 392 | T::waker().register(cx.waker()); |
| @@ -398,6 +422,10 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 398 | }); | 422 | }); |
| 399 | } | 423 | } |
| 400 | 424 | ||
| 425 | if sr.rxhrstdet() { | ||
| 426 | r.imr().modify(|w| w.set_rxhrstdetie(false)); | ||
| 427 | } | ||
| 428 | |||
| 401 | if sr.rxmsgend() { | 429 | if sr.rxmsgend() { |
| 402 | r.imr().modify(|w| w.set_rxmsgendie(false)); | 430 | r.imr().modify(|w| w.set_rxmsgendie(false)); |
| 403 | } | 431 | } |
