aboutsummaryrefslogtreecommitdiff
path: root/tests/stm32/src/bin
diff options
context:
space:
mode:
authorTimo Kröger <[email protected]>2024-03-15 17:45:48 +0100
committerTimo Kröger <[email protected]>2024-03-15 17:49:15 +0100
commit067e677ae5c3c765bca1db6e4cb7aef5de163086 (patch)
tree80ac059d7a21d7415c676641dea81e479918c275 /tests/stm32/src/bin
parent21e2499f353c995d71710a2ed62d6f3914d6d60c (diff)
[UCPD] Add unit test for stm32g071rb board
One test for changing the CC line pull-up resistor is skipped for now.
Diffstat (limited to 'tests/stm32/src/bin')
-rw-r--r--tests/stm32/src/bin/ucpd.rs119
1 files changed, 119 insertions, 0 deletions
diff --git a/tests/stm32/src/bin/ucpd.rs b/tests/stm32/src/bin/ucpd.rs
new file mode 100644
index 000000000..daaa56c32
--- /dev/null
+++ b/tests/stm32/src/bin/ucpd.rs
@@ -0,0 +1,119 @@
1#![no_std]
2#![no_main]
3#[path = "../common.rs"]
4mod common;
5
6use common::*;
7use defmt::{assert, assert_eq};
8use embassy_executor::Spawner;
9use embassy_futures::join::join;
10use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd};
11use embassy_stm32::{bind_interrupts, peripherals};
12use embassy_time::Timer;
13
14bind_interrupts!(struct Irqs {
15 UCPD1_2 => ucpd::InterruptHandler<peripherals::UCPD1>, ucpd::InterruptHandler<peripherals::UCPD2>;
16});
17
18static SRC_TO_SNK: [u8; 6] = [0, 1, 2, 3, 4, 5];
19static SNK_TO_SRC: [u8; 4] = [9, 8, 7, 6];
20
21async fn wait_for_vstate<T: ucpd::Instance>(cc_phy: &mut CcPhy<'_, T>, vstate: CcVState) {
22 let (mut cc1, mut _cc2) = cc_phy.vstate();
23 while cc1 != vstate {
24 (cc1, _cc2) = cc_phy.wait_for_vstate_change().await;
25 }
26}
27
28async fn source(
29 mut ucpd: Ucpd<'static, peripherals::UCPD1>,
30 rx_dma: peripherals::DMA1_CH1,
31 tx_dma: peripherals::DMA1_CH2,
32) {
33 debug!("source: setting default current pull-up");
34 ucpd.cc_phy().set_pull(CcPull::SourceDefaultUsb);
35
36 // Wait for default sink.
37 debug!("source: wait for sink");
38 wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await;
39
40 // Advertise a higher current by changing the pull-up resistor.
41 debug!("source: sink detected, setting 3.0A current pull-up");
42 ucpd.cc_phy().set_pull(CcPull::Source3_0A);
43
44 let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1);
45
46 // Listen for an incoming message
47 debug!("source: wait for message from sink");
48 let mut snk_to_src_buf = [0_u8; 30];
49 let n = unwrap!(pd_phy.receive(snk_to_src_buf.as_mut()).await);
50 assert_eq!(n, SNK_TO_SRC.len());
51 assert_eq!(&snk_to_src_buf[..n], SNK_TO_SRC.as_slice());
52
53 // Send message
54 debug!("source: message received, sending message");
55 unwrap!(pd_phy.transmit(SRC_TO_SNK.as_slice()).await);
56
57 // Wait for hard-reset
58 debug!("source: message sent, waiting for hard-reset");
59 assert!(matches!(
60 pd_phy.receive(snk_to_src_buf.as_mut()).await,
61 Err(RxError::HardReset)
62 ));
63}
64
65async fn sink(
66 mut ucpd: Ucpd<'static, peripherals::UCPD2>,
67 rx_dma: peripherals::DMA1_CH3,
68 tx_dma: peripherals::DMA1_CH4,
69) {
70 debug!("sink: setting pull down");
71 ucpd.cc_phy().set_pull(CcPull::Sink);
72
73 // Wait for default source.
74 debug!("sink: waiting for default vstate");
75 wait_for_vstate(ucpd.cc_phy(), CcVState::LOW).await;
76
77 // Wait higher current pull-up.
78 //debug!("sink: source default vstate detected, waiting for 3.0A vstate");
79 //wait_for_vstate(ucpd.cc_phy(), CcVState::HIGHEST).await;
80 //debug!("sink: source 3.0A vstate detected");
81 // TODO: not working yet, why? no idea, replace with timer for now
82 Timer::after_millis(100).await;
83
84 let (_, mut pd_phy) = ucpd.split_pd_phy(rx_dma, tx_dma, CcSel::CC1);
85
86 // Send message
87 debug!("sink: sending message");
88 unwrap!(pd_phy.transmit(SNK_TO_SRC.as_slice()).await);
89
90 // Listen for an incoming message
91 debug!("sink: message sent, waiting for message from source");
92 let mut src_to_snk_buf = [0_u8; 30];
93 let n = unwrap!(pd_phy.receive(src_to_snk_buf.as_mut()).await);
94 assert_eq!(n, SRC_TO_SNK.len());
95 assert_eq!(&src_to_snk_buf[..n], SRC_TO_SNK.as_slice());
96
97 // Send hard reset
98 debug!("sink: message received, sending hard-reset");
99 unwrap!(pd_phy.transmit_hardreset().await);
100}
101
102#[embassy_executor::main]
103async fn main(_spawner: Spawner) {
104 let p = embassy_stm32::init(config());
105 info!("Hello World!");
106
107 // Wire between PD0 and PA8
108 let ucpd1 = Ucpd::new(p.UCPD1, Irqs {}, p.PA8, p.PB15);
109 let ucpd2 = Ucpd::new(p.UCPD2, Irqs {}, p.PD0, p.PD2);
110
111 join(
112 source(ucpd1, p.DMA1_CH1, p.DMA1_CH2),
113 sink(ucpd2, p.DMA1_CH3, p.DMA1_CH4),
114 )
115 .await;
116
117 info!("Test OK");
118 cortex_m::asm::bkpt();
119}