From 4d0e3838168a7447b3580135ef78d65baa578933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Kro=CC=88ger?= Date: Thu, 7 Mar 2024 11:17:39 +0100 Subject: [PATCH] [UCPD] Prepare for PD communication implementation --- embassy-stm32/src/ucpd.rs | 47 +++++++++++++++++++++++++++- examples/stm32g4/src/bin/usb_c_pd.rs | 15 ++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/embassy-stm32/src/ucpd.rs b/embassy-stm32/src/ucpd.rs index a366fadda..96cd92764 100644 --- a/embassy-stm32/src/ucpd.rs +++ b/embassy-stm32/src/ucpd.rs @@ -22,9 +22,10 @@ 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::interrupt; -pub use crate::pac::ucpd::vals::TypecVstateCc as CcVState; use crate::pac::ucpd::vals::{Anamode, Ccenable, PscUsbpdclk}; +pub use crate::pac::ucpd::vals::{Phyccsel as CcSel, TypecVstateCc as CcVState}; use crate::rcc::RccPeripheral; /// Pull-up or Pull-down resistor state of both CC lines. @@ -177,6 +178,50 @@ impl<'d, T: Instance> Ucpd<'d, T> { }) }); } + + /// Returns PD receiver and transmitter. + pub fn pd( + &mut self, + rx_dma: impl Peripheral

> + 'd, + tx_dma: impl Peripheral

> + 'd, + cc_sel: CcSel, + ) -> (PdRx<'_, T>, PdTx<'_, T>) { + into_ref!(rx_dma, tx_dma); + let rx_dma_req = rx_dma.request(); + let tx_dma_req = tx_dma.request(); + ( + PdRx { + _ucpd: self, + dma_ch: rx_dma.map_into(), + dma_req: rx_dma_req, + }, + PdTx { + _ucpd: self, + dma_ch: tx_dma.map_into(), + dma_req: tx_dma_req, + }, + ) + } +} + +/// Power Delivery (PD) Receiver. +pub struct PdRx<'d, T: Instance> { + _ucpd: &'d Ucpd<'d, T>, + dma_ch: PeripheralRef<'d, AnyChannel>, + dma_req: Request, +} + +impl<'d, T: Instance> Drop for PdRx<'d, T> { + fn drop(&mut self) { + T::REGS.cr().modify(|w| w.set_phyrxen(false)); + } +} + +/// Power Delivery (PD) Transmitter. +pub struct PdTx<'d, T: Instance> { + _ucpd: &'d Ucpd<'d, T>, + dma_ch: PeripheralRef<'d, AnyChannel>, + dma_req: Request, } /// Interrupt handler. diff --git a/examples/stm32g4/src/bin/usb_c_pd.rs b/examples/stm32g4/src/bin/usb_c_pd.rs index 7a0065087..1443cb773 100644 --- a/examples/stm32g4/src/bin/usb_c_pd.rs +++ b/examples/stm32g4/src/bin/usb_c_pd.rs @@ -3,7 +3,7 @@ use defmt::{info, Format}; use embassy_executor::Spawner; -use embassy_stm32::ucpd::{self, CcPull, CcVState, Ucpd}; +use embassy_stm32::ucpd::{self, CcPull, CcSel, CcVState, Ucpd}; use embassy_stm32::Config; use embassy_time::{with_timeout, Duration}; use {defmt_rtt as _, panic_probe as _}; @@ -56,5 +56,18 @@ async fn main(_spawner: Spawner) { let cable_orientation = wait_attached(&mut ucpd).await; info!("USB cable connected, orientation: {}", cable_orientation); + let cc_sel = match cable_orientation { + CableOrientation::Normal => { + info!("Starting PD communication on CC1 pin"); + CcSel::CC1 + } + CableOrientation::Flipped => { + info!("Starting PD communication on CC2 pin"); + CcSel::CC2 + } + CableOrientation::DebugAccessoryMode => panic!("No PD communication in DAM"), + }; + let (mut _rx, mut _tx) = ucpd.pd(p.DMA1_CH1, p.DMA1_CH2, cc_sel); + loop {} }