-
Notifications
You must be signed in to change notification settings - Fork 829
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use defmt::{error, info, Format}; | ||
use embassy_executor::Spawner; | ||
use embassy_stm32::gpio::Output; | ||
use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, Ucpd}; | ||
use embassy_stm32::{bind_interrupts, peripherals, Config}; | ||
use embassy_time::{with_timeout, Duration}; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
|
||
bind_interrupts!(struct Irqs { | ||
UCPD1 => ucpd::InterruptHandler<peripherals::UCPD1>; | ||
}); | ||
|
||
#[derive(Debug, Format)] | ||
enum CableOrientation { | ||
Normal, | ||
Flipped, | ||
DebugAccessoryMode, | ||
} | ||
|
||
// Returns true when the cable | ||
async fn wait_attached<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>) -> CableOrientation { | ||
loop { | ||
let (cc1, cc2) = cc_phy.vstate(); | ||
if cc1 == CcVState::LOWEST && cc2 == CcVState::LOWEST { | ||
// Detached, wait until attached by monitoring the CC lines. | ||
cc_phy.wait_for_vstate_change().await; | ||
continue; | ||
} | ||
|
||
// Attached, wait for CC lines to be stable for tCCDebounce (100..200ms). | ||
if with_timeout(Duration::from_millis(100), cc_phy.wait_for_vstate_change()) | ||
.await | ||
.is_ok() | ||
{ | ||
// State has changed, restart detection procedure. | ||
continue; | ||
}; | ||
|
||
// State was stable for the complete debounce period, check orientation. | ||
return match (cc1, cc2) { | ||
(_, CcVState::LOWEST) => CableOrientation::Normal, // CC1 connected | ||
(CcVState::LOWEST, _) => CableOrientation::Flipped, // CC2 connected | ||
_ => CableOrientation::DebugAccessoryMode, // Both connected (special cable) | ||
}; | ||
} | ||
} | ||
|
||
#[embassy_executor::main] | ||
async fn main(_spawner: Spawner) { | ||
let config = Config::default(); | ||
let p = embassy_stm32::init(config); | ||
|
||
info!("Hello World!"); | ||
|
||
// This pin controls the dead-battery mode on the attached TCPP01-M12. | ||
// If low, TCPP01-M12 disconnects CC lines and presents dead-battery resistance on CC lines, thus set high. | ||
let _tcpp01_m12_ndb = Output::new(p.PA9, embassy_stm32::gpio::Level::High, embassy_stm32::gpio::Speed::Low); | ||
|
||
let mut ucpd = Ucpd::new(p.UCPD1, Irqs {}, p.PB13, p.PB14, Default::default()); | ||
ucpd.cc_phy().set_pull(CcPull::Sink); | ||
|
||
info!("Waiting for USB connection..."); | ||
let cable_orientation = wait_attached(ucpd.cc_phy()).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 (_cc_phy, mut pd_phy) = ucpd.split_pd_phy(p.GPDMA1_CH0, p.GPDMA1_CH1, cc_sel); | ||
|
||
loop { | ||
// Enough space for the longest non-extended data message. | ||
let mut buf = [0_u8; 30]; | ||
match pd_phy.receive(buf.as_mut()).await { | ||
Ok(n) => info!("USB PD RX: {=[u8]:?}", &buf[..n]), | ||
Err(e) => error!("USB PD RX: {}", e), | ||
} | ||
} | ||
} |