diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index 96cd92764..f3f225d0c 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs @@ -22,7 +22,7 @@ use embassy_hal_internal::drop::OnDrop; use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; use embassy_sync::waitqueue::AtomicWaker; -use crate::dma::AnyChannel; +use crate::dma::{AnyChannel, Request, Transfer, TransferOptions}; use crate::interrupt; use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk}; pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, TypecVstateCc as CcVState}; @@ -99,7 +99,7 @@ impl<'d, T: Instance> Ucpd<'d, T> { // 1.75us * 17 = ~30us w.set_ifrgap(17 - 1); - // TODO: Only receive SOP messages + // TODO: Currently only SOP messages are supported. w.set_rxordseten(0x1); // Enable DMA and the peripheral @@ -186,6 +186,14 @@ impl<'d, T: Instance> Ucpd<'d, T> { tx_dma: impl Peripheral
> + 'd,
cc_sel: CcSel,
) -> (PdRx<'_, T>, PdTx<'_, T>) {
+ let r = T::REGS;
+
+ // Enable the receiver on one of the two CC lines.
+ r.cr().modify(|w| {
+ w.set_phyccsel(cc_sel);
+ w.set_phyrxen(true);
+ });
+
into_ref!(rx_dma, tx_dma);
let rx_dma_req = rx_dma.request();
let tx_dma_req = tx_dma.request();
@@ -204,6 +212,16 @@ impl<'d, T: Instance> Ucpd<'d, T> {
}
}
+/// Receive Error.
+#[derive(Debug, Clone, Copy)]
+pub enum RxError {
+ /// Incorrect CRC or truncated message (a line becoming static before EOP is met).
+ Crc,
+
+ /// Provided buffer was too small for the received message.
+ Overrun,
+}
+
/// Power Delivery (PD) Receiver.
pub struct PdRx<'d, T: Instance> {
_ucpd: &'d Ucpd<'d, T>,
@@ -217,6 +235,79 @@ impl<'d, T: Instance> Drop for PdRx<'d, T> {
}
}
+impl<'d, T: Instance> PdRx<'d, T> {
+ /// Receives a PD message into the provided buffer.
+ ///
+ /// Returns the number of received bytes or an error.
+ pub async fn receive(&mut self, buf: &mut [u8]) -> Result