diff options
| author | Timo Kröger <[email protected]> | 2024-03-15 17:45:48 +0100 |
|---|---|---|
| committer | Timo Kröger <[email protected]> | 2024-03-15 17:49:15 +0100 |
| commit | 067e677ae5c3c765bca1db6e4cb7aef5de163086 (patch) | |
| tree | 80ac059d7a21d7415c676641dea81e479918c275 /tests | |
| parent | 21e2499f353c995d71710a2ed62d6f3914d6d60c (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')
| -rw-r--r-- | tests/stm32/Cargo.toml | 8 | ||||
| -rw-r--r-- | tests/stm32/src/bin/ucpd.rs | 119 |
2 files changed, 126 insertions, 1 deletions
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index bfe003a11..0332fc526 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -13,7 +13,7 @@ stm32f303ze = ["embassy-stm32/stm32f303ze", "chrono", "not-gpdma"] | |||
| 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] | 13 | stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "eth", "stop", "can", "not-gpdma", "dac", "rng"] |
| 14 | stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] | 14 | stm32f446re = ["embassy-stm32/stm32f446re", "chrono", "stop", "can", "not-gpdma", "dac", "sdmmc"] |
| 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] | 15 | stm32f767zi = ["embassy-stm32/stm32f767zi", "chrono", "not-gpdma", "eth", "rng"] |
| 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac"] | 16 | stm32g071rb = ["embassy-stm32/stm32g071rb", "cm0", "not-gpdma", "dac", "ucpd"] |
| 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"] | 17 | stm32g491re = ["embassy-stm32/stm32g491re", "chrono", "stop", "not-gpdma", "rng", "fdcan"] |
| 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"] | 18 | stm32h563zi = ["embassy-stm32/stm32h563zi", "chrono", "eth", "rng", "hash"] |
| 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] | 19 | stm32h753zi = ["embassy-stm32/stm32h753zi", "chrono", "not-gpdma", "eth", "rng", "fdcan", "hash", "cryp"] |
| @@ -47,6 +47,7 @@ mac = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/mac"] | |||
| 47 | embassy-stm32-wpan = [] | 47 | embassy-stm32-wpan = [] |
| 48 | not-gpdma = [] | 48 | not-gpdma = [] |
| 49 | dac = [] | 49 | dac = [] |
| 50 | ucpd = [] | ||
| 50 | 51 | ||
| 51 | cm0 = ["portable-atomic/unsafe-assume-single-core"] | 52 | cm0 = ["portable-atomic/unsafe-assume-single-core"] |
| 52 | 53 | ||
| @@ -161,6 +162,11 @@ path = "src/bin/timer.rs" | |||
| 161 | required-features = [] | 162 | required-features = [] |
| 162 | 163 | ||
| 163 | [[bin]] | 164 | [[bin]] |
| 165 | name = "ucpd" | ||
| 166 | path = "src/bin/ucpd.rs" | ||
| 167 | required-features = [] | ||
| 168 | |||
| 169 | [[bin]] | ||
| 164 | name = "usart" | 170 | name = "usart" |
| 165 | path = "src/bin/usart.rs" | 171 | path = "src/bin/usart.rs" |
| 166 | required-features = [] | 172 | required-features = [] |
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"] | ||
| 4 | mod common; | ||
| 5 | |||
| 6 | use common::*; | ||
| 7 | use defmt::{assert, assert_eq}; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_futures::join::join; | ||
| 10 | use embassy_stm32::ucpd::{self, CcPhy, CcPull, CcSel, CcVState, RxError, Ucpd}; | ||
| 11 | use embassy_stm32::{bind_interrupts, peripherals}; | ||
| 12 | use embassy_time::Timer; | ||
| 13 | |||
| 14 | bind_interrupts!(struct Irqs { | ||
| 15 | UCPD1_2 => ucpd::InterruptHandler<peripherals::UCPD1>, ucpd::InterruptHandler<peripherals::UCPD2>; | ||
| 16 | }); | ||
| 17 | |||
| 18 | static SRC_TO_SNK: [u8; 6] = [0, 1, 2, 3, 4, 5]; | ||
| 19 | static SNK_TO_SRC: [u8; 4] = [9, 8, 7, 6]; | ||
| 20 | |||
| 21 | async 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 | |||
| 28 | async 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 | |||
| 65 | async 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] | ||
| 103 | async 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 | } | ||
