aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2024-03-08 15:15:55 +0100
committerTimo Kröger <[email protected]>2024-03-12 08:14:42 +0100
commitff8129a6a6845186bac92c6b6fcfefa03a7a7d4d (patch)
treec0bca2cfa6f5635ffefa701ffe5168ad6a53ac92
parentc1efcbba2dc472948b294b474a9a1970f88cd96a (diff)
[UCPD] Implement hard reset transmission
-rw-r--r--embassy-stm32/src/ucpd.rs51
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 }