diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-09-20 13:47:25 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-20 13:47:25 +0000 |
| commit | 3020bf36622f9e0603f7b9a2e29070fc7d83f11b (patch) | |
| tree | 4be5ddca07a3ddf69546e26cdb9de1878425a093 | |
| parent | d7780fcf83a8a35d7b09e5df7b62dd8218436715 (diff) | |
| parent | 5ea934d4ba6f0bc0e5e47b16f17dd8e881b528a3 (diff) | |
Merge pull request #3355 from Gerharddc/main
embassy_stm32/eth: support compliance testing
| -rw-r--r-- | embassy-stm32/src/eth/mod.rs | 14 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/eth_compliance_test.rs | 77 |
2 files changed, 91 insertions, 0 deletions
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index bfe8a60d6..6442176da 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs | |||
| @@ -177,6 +177,20 @@ pub unsafe trait PHY { | |||
| 177 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; | 177 | fn poll_link<S: StationManagement>(&mut self, sm: &mut S, cx: &mut Context) -> bool; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { | ||
| 181 | /// Directly expose the SMI interface used by the Ethernet driver. | ||
| 182 | /// | ||
| 183 | /// This can be used to for example configure special PHY registers for compliance testing. | ||
| 184 | /// | ||
| 185 | /// # Safety | ||
| 186 | /// | ||
| 187 | /// Revert any temporary PHY register changes such as to enable test modes before handing | ||
| 188 | /// the Ethernet device over to the networking stack otherwise things likely won't work. | ||
| 189 | pub unsafe fn station_management(&mut self) -> &mut impl StationManagement { | ||
| 190 | &mut self.station_management | ||
| 191 | } | ||
| 192 | } | ||
| 193 | |||
| 180 | trait SealedInstance { | 194 | trait SealedInstance { |
| 181 | fn regs() -> crate::pac::eth::Eth; | 195 | fn regs() -> crate::pac::eth::Eth; |
| 182 | } | 196 | } |
diff --git a/examples/stm32f4/src/bin/eth_compliance_test.rs b/examples/stm32f4/src/bin/eth_compliance_test.rs new file mode 100644 index 000000000..5946fed79 --- /dev/null +++ b/examples/stm32f4/src/bin/eth_compliance_test.rs | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | |||
| 4 | use defmt::*; | ||
| 5 | use embassy_executor::Spawner; | ||
| 6 | use embassy_stm32::eth::generic_smi::GenericSMI; | ||
| 7 | use embassy_stm32::eth::{Ethernet, PacketQueue, StationManagement}; | ||
| 8 | use embassy_stm32::time::Hertz; | ||
| 9 | use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | ||
| 10 | use embassy_time::Timer; | ||
| 11 | use static_cell::StaticCell; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | bind_interrupts!(struct Irqs { | ||
| 15 | ETH => eth::InterruptHandler; | ||
| 16 | HASH_RNG => rng::InterruptHandler<peripherals::RNG>; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) -> ! { | ||
| 21 | let mut config = Config::default(); | ||
| 22 | { | ||
| 23 | use embassy_stm32::rcc::*; | ||
| 24 | config.rcc.hse = Some(Hse { | ||
| 25 | freq: Hertz(8_000_000), | ||
| 26 | mode: HseMode::Bypass, | ||
| 27 | }); | ||
| 28 | config.rcc.pll_src = PllSource::HSE; | ||
| 29 | config.rcc.pll = Some(Pll { | ||
| 30 | prediv: PllPreDiv::DIV4, | ||
| 31 | mul: PllMul::MUL180, | ||
| 32 | divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 180 / 2 = 180Mhz. | ||
| 33 | divq: None, | ||
| 34 | divr: None, | ||
| 35 | }); | ||
| 36 | config.rcc.ahb_pre = AHBPrescaler::DIV1; | ||
| 37 | config.rcc.apb1_pre = APBPrescaler::DIV4; | ||
| 38 | config.rcc.apb2_pre = APBPrescaler::DIV2; | ||
| 39 | config.rcc.sys = Sysclk::PLL1_P; | ||
| 40 | } | ||
| 41 | let p = embassy_stm32::init(config); | ||
| 42 | |||
| 43 | info!("Hello Compliance World!"); | ||
| 44 | |||
| 45 | let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||
| 46 | |||
| 47 | const PHY_ADDR: u8 = 0; | ||
| 48 | static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); | ||
| 49 | let mut device = Ethernet::new( | ||
| 50 | PACKETS.init(PacketQueue::<4, 4>::new()), | ||
| 51 | p.ETH, | ||
| 52 | Irqs, | ||
| 53 | p.PA1, | ||
| 54 | p.PA2, | ||
| 55 | p.PC1, | ||
| 56 | p.PA7, | ||
| 57 | p.PC4, | ||
| 58 | p.PC5, | ||
| 59 | p.PG13, | ||
| 60 | p.PB13, | ||
| 61 | p.PG11, | ||
| 62 | GenericSMI::new(PHY_ADDR), | ||
| 63 | mac_addr, | ||
| 64 | ); | ||
| 65 | |||
| 66 | let sm = unsafe { device.station_management() }; | ||
| 67 | |||
| 68 | // Just an example. Exact register settings depend on the specific PHY and test. | ||
| 69 | sm.smi_write(PHY_ADDR, 0, 0x2100); | ||
| 70 | sm.smi_write(PHY_ADDR, 11, 0xA000); | ||
| 71 | |||
| 72 | // NB: Remember to reset the PHY after testing before starting the networking stack | ||
| 73 | |||
| 74 | loop { | ||
| 75 | Timer::after_secs(1).await; | ||
| 76 | } | ||
| 77 | } | ||
