diff options
| author | Timo Kröger <[email protected]> | 2024-03-03 15:09:53 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2024-03-12 08:14:42 +0100 |
| commit | d99fcfd0c285be220c8f0004974567d7d4e2607b (patch) | |
| tree | d8ede531bccce63766bb44c6a4ecdbcde8ff6729 /examples/stm32g4/src/bin | |
| parent | aa1411e2c772fd332417ca258b58c75b35d5b7ac (diff) | |
[UCPD] Configuration Channel (CC) handling
Diffstat (limited to 'examples/stm32g4/src/bin')
| -rw-r--r-- | examples/stm32g4/src/bin/usb_c_pd.rs | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/examples/stm32g4/src/bin/usb_c_pd.rs b/examples/stm32g4/src/bin/usb_c_pd.rs new file mode 100644 index 000000000..c442ab0a7 --- /dev/null +++ b/examples/stm32g4/src/bin/usb_c_pd.rs | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::{info, Format}; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::{ | ||
| 7 | ucpd::{self, CcPull, CcVState, Ucpd}, | ||
| 8 | Config, | ||
| 9 | }; | ||
| 10 | use embassy_time::{with_timeout, Duration}; | ||
| 11 | use {defmt_rtt as _, panic_probe as _}; | ||
| 12 | |||
| 13 | #[derive(Debug, Format)] | ||
| 14 | enum CableOrientation { | ||
| 15 | Normal, | ||
| 16 | Flipped, | ||
| 17 | DebugAccessoryMode, | ||
| 18 | } | ||
| 19 | |||
| 20 | // Returns true when the cable | ||
| 21 | async fn wait_attached<'d, T: ucpd::Instance>(ucpd: &mut Ucpd<'d, T>) -> CableOrientation { | ||
| 22 | loop { | ||
| 23 | let (cc1, cc2) = ucpd.cc_vstate(); | ||
| 24 | if cc1 == CcVState::LOWEST && cc2 == CcVState::LOWEST { | ||
| 25 | // Detached, wait until attached by monitoring the CC lines. | ||
| 26 | ucpd.wait_for_cc_change().await; | ||
| 27 | continue; | ||
| 28 | } | ||
| 29 | |||
| 30 | // Attached, wait for CC lines to be stable for tCCDebounce (100..200ms). | ||
| 31 | if with_timeout(Duration::from_millis(100), ucpd.wait_for_cc_change()) | ||
| 32 | .await | ||
| 33 | .is_ok() | ||
| 34 | { | ||
| 35 | // State has changed, restart detection procedure. | ||
| 36 | continue; | ||
| 37 | }; | ||
| 38 | |||
| 39 | // State was stable for the complete debounce period, check orientation. | ||
| 40 | return match (cc1, cc2) { | ||
| 41 | (_, CcVState::LOWEST) => CableOrientation::Normal, // CC1 connected | ||
| 42 | (CcVState::LOWEST, _) => CableOrientation::Flipped, // CC2 connected | ||
| 43 | _ => CableOrientation::DebugAccessoryMode, // Both connected (special cable) | ||
| 44 | }; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | #[embassy_executor::main] | ||
| 49 | async fn main(_spawner: Spawner) { | ||
| 50 | // TODO: Disable DBCC pin functionality by default but have flag in the config to keep it enabled when required. | ||
| 51 | let p = embassy_stm32::init(Config::default()); | ||
| 52 | |||
| 53 | info!("Hello World!"); | ||
| 54 | |||
| 55 | let mut ucpd = Ucpd::new(p.UCPD1, p.PB6, p.PB4, CcPull::Sink); | ||
| 56 | |||
| 57 | info!("Waiting for USB connection..."); | ||
| 58 | let cable_orientation = wait_attached(&mut ucpd).await; | ||
| 59 | info!("USB cable connected, orientation: {}", cable_orientation); | ||
| 60 | |||
| 61 | loop {} | ||
| 62 | } | ||
