diff options
| -rw-r--r-- | embassy-stm32/src/ucpd.rs | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index 64969beb8..05a61634a 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs | |||
| @@ -403,6 +403,50 @@ impl<'d, T: Instance> PdPhy<'d, T> { | |||
| 403 | w.set_txmsgsentie(enable); | 403 | w.set_txmsgsentie(enable); |
| 404 | }); | 404 | }); |
| 405 | } | 405 | } |
| 406 | |||
| 407 | /// Transmit a hard reset. | ||
| 408 | pub async fn transmit_hardreset(&mut self) -> Result<(), TxError> { | ||
| 409 | let r = T::REGS; | ||
| 410 | |||
| 411 | // Clear the hardreset interrupt flags. | ||
| 412 | T::REGS.icr().write(|w| { | ||
| 413 | w.set_txmsgdisccf(true); | ||
| 414 | w.set_txmsgsentcf(true); | ||
| 415 | }); | ||
| 416 | |||
| 417 | // Trigger hard reset transmission. | ||
| 418 | r.cr().modify(|w| { | ||
| 419 | w.set_txhrst(true); | ||
| 420 | }); | ||
| 421 | |||
| 422 | let _on_drop = OnDrop::new(|| self.enable_hardreset_interrupts(false)); | ||
| 423 | poll_fn(|cx| { | ||
| 424 | let r = T::REGS; | ||
| 425 | let sr = r.sr().read(); | ||
| 426 | if sr.rxhrstdet() { | ||
| 427 | // Clean and re-enable hard reset receive interrupt. | ||
| 428 | r.icr().write(|w| w.set_rxhrstdetcf(true)); | ||
| 429 | r.imr().modify(|w| w.set_rxhrstdetie(true)); | ||
| 430 | Poll::Ready(Err(TxError::HardReset)) | ||
| 431 | } else if sr.hrstdisc() { | ||
| 432 | Poll::Ready(Err(TxError::Discarded)) | ||
| 433 | } else if sr.hrstsent() { | ||
| 434 | Poll::Ready(Ok(())) | ||
| 435 | } else { | ||
| 436 | T::waker().register(cx.waker()); | ||
| 437 | self.enable_hardreset_interrupts(true); | ||
| 438 | Poll::Pending | ||
| 439 | } | ||
| 440 | }) | ||
| 441 | .await | ||
| 442 | } | ||
| 443 | |||
| 444 | fn enable_hardreset_interrupts(&self, enable: bool) { | ||
| 445 | T::REGS.imr().modify(|w| { | ||
| 446 | w.set_hrstdiscie(enable); | ||
| 447 | w.set_hrstsentie(enable); | ||
| 448 | }); | ||
| 449 | } | ||
| 406 | } | 450 | } |
| 407 | 451 | ||
| 408 | /// Interrupt handler. | 452 | /// Interrupt handler. |
| @@ -437,6 +481,13 @@ impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandl | |||
| 437 | }); | 481 | }); |
| 438 | } | 482 | } |
| 439 | 483 | ||
| 484 | if sr.hrstdisc() || sr.hrstsent() { | ||
| 485 | r.imr().modify(|w| { | ||
| 486 | w.set_hrstdiscie(false); | ||
| 487 | w.set_hrstsentie(false); | ||
| 488 | }); | ||
| 489 | } | ||
| 490 | |||
| 440 | // Wake the task to clear and re-enabled interrupts. | 491 | // Wake the task to clear and re-enabled interrupts. |
| 441 | T::waker().wake(); | 492 | T::waker().wake(); |
| 442 | } | 493 | } |
