aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon B. Gasse <[email protected]>2024-01-19 21:10:03 +0100
committerDario Nieuwenhuis <[email protected]>2024-02-01 01:33:34 +0100
commit42d8f3930a861dcc4540198bf2038151eb4e3e27 (patch)
treea188a1489792563413a9330d9fb74d7cb42dd01a
parente05f6505ae18696ad178119c747775b7e839ae8d (diff)
Implement MII interface
- Extend the eth/v2 module to support MII besides RMII. - Replace `Ethernet::new` with `Ethernet::new_mii` and `Ethernet::new_rmii`. - Update ethernet examples. - Add example for MII ethernet.
-rw-r--r--embassy-stm32/build.rs7
-rw-r--r--embassy-stm32/src/eth/mod.rs7
-rw-r--r--embassy-stm32/src/eth/v2/mod.rs136
-rw-r--r--examples/stm32f4/src/bin/eth.rs2
-rw-r--r--examples/stm32f7/src/bin/eth.rs2
-rw-r--r--examples/stm32h5/src/bin/eth.rs2
-rw-r--r--examples/stm32h7/src/bin/eth.rs2
-rw-r--r--examples/stm32h7/src/bin/eth_client.rs2
-rw-r--r--examples/stm32h7/src/bin/eth_client_mii.rs142
-rw-r--r--tests/stm32/src/bin/eth.rs21
10 files changed, 295 insertions, 28 deletions
diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs
index 414723573..bd4195619 100644
--- a/embassy-stm32/build.rs
+++ b/embassy-stm32/build.rs
@@ -735,13 +735,20 @@ fn main() {
735 (("can", "TX"), quote!(crate::can::TxPin)), 735 (("can", "TX"), quote!(crate::can::TxPin)),
736 (("can", "RX"), quote!(crate::can::RxPin)), 736 (("can", "RX"), quote!(crate::can::RxPin)),
737 (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)), 737 (("eth", "REF_CLK"), quote!(crate::eth::RefClkPin)),
738 (("eth", "RX_CLK"), quote!(crate::eth::RXClkPin)),
739 (("eth", "TX_CLK"), quote!(crate::eth::TXClkPin)),
738 (("eth", "MDIO"), quote!(crate::eth::MDIOPin)), 740 (("eth", "MDIO"), quote!(crate::eth::MDIOPin)),
739 (("eth", "MDC"), quote!(crate::eth::MDCPin)), 741 (("eth", "MDC"), quote!(crate::eth::MDCPin)),
740 (("eth", "CRS_DV"), quote!(crate::eth::CRSPin)), 742 (("eth", "CRS_DV"), quote!(crate::eth::CRSPin)),
743 (("eth", "RX_DV"), quote!(crate::eth::RXDVPin)),
741 (("eth", "RXD0"), quote!(crate::eth::RXD0Pin)), 744 (("eth", "RXD0"), quote!(crate::eth::RXD0Pin)),
742 (("eth", "RXD1"), quote!(crate::eth::RXD1Pin)), 745 (("eth", "RXD1"), quote!(crate::eth::RXD1Pin)),
746 (("eth", "RXD2"), quote!(crate::eth::RXD2Pin)),
747 (("eth", "RXD3"), quote!(crate::eth::RXD3Pin)),
743 (("eth", "TXD0"), quote!(crate::eth::TXD0Pin)), 748 (("eth", "TXD0"), quote!(crate::eth::TXD0Pin)),
744 (("eth", "TXD1"), quote!(crate::eth::TXD1Pin)), 749 (("eth", "TXD1"), quote!(crate::eth::TXD1Pin)),
750 (("eth", "TXD2"), quote!(crate::eth::TXD2Pin)),
751 (("eth", "TXD3"), quote!(crate::eth::TXD3Pin)),
745 (("eth", "TX_EN"), quote!(crate::eth::TXEnPin)), 752 (("eth", "TX_EN"), quote!(crate::eth::TXEnPin)),
746 (("fmc", "A0"), quote!(crate::fmc::A0Pin)), 753 (("fmc", "A0"), quote!(crate::fmc::A0Pin)),
747 (("fmc", "A1"), quote!(crate::fmc::A1Pin)), 754 (("fmc", "A1"), quote!(crate::fmc::A1Pin)),
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 448405507..fbcdd7fae 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -192,12 +192,19 @@ impl sealed::Instance for crate::peripherals::ETH {
192} 192}
193impl Instance for crate::peripherals::ETH {} 193impl Instance for crate::peripherals::ETH {}
194 194
195pin_trait!(RXClkPin, Instance);
196pin_trait!(TXClkPin, Instance);
195pin_trait!(RefClkPin, Instance); 197pin_trait!(RefClkPin, Instance);
196pin_trait!(MDIOPin, Instance); 198pin_trait!(MDIOPin, Instance);
197pin_trait!(MDCPin, Instance); 199pin_trait!(MDCPin, Instance);
200pin_trait!(RXDVPin, Instance);
198pin_trait!(CRSPin, Instance); 201pin_trait!(CRSPin, Instance);
199pin_trait!(RXD0Pin, Instance); 202pin_trait!(RXD0Pin, Instance);
200pin_trait!(RXD1Pin, Instance); 203pin_trait!(RXD1Pin, Instance);
204pin_trait!(RXD2Pin, Instance);
205pin_trait!(RXD3Pin, Instance);
201pin_trait!(TXD0Pin, Instance); 206pin_trait!(TXD0Pin, Instance);
202pin_trait!(TXD1Pin, Instance); 207pin_trait!(TXD1Pin, Instance);
208pin_trait!(TXD2Pin, Instance);
209pin_trait!(TXD3Pin, Instance);
203pin_trait!(TXEnPin, Instance); 210pin_trait!(TXEnPin, Instance);
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs
index 59745cba0..a176b01e5 100644
--- a/embassy-stm32/src/eth/v2/mod.rs
+++ b/embassy-stm32/src/eth/v2/mod.rs
@@ -39,12 +39,18 @@ pub struct Ethernet<'d, T: Instance, P: PHY> {
39 _peri: PeripheralRef<'d, T>, 39 _peri: PeripheralRef<'d, T>,
40 pub(crate) tx: TDesRing<'d>, 40 pub(crate) tx: TDesRing<'d>,
41 pub(crate) rx: RDesRing<'d>, 41 pub(crate) rx: RDesRing<'d>,
42 pins: [PeripheralRef<'d, AnyPin>; 9], 42 pins: Pins<'d>,
43 pub(crate) phy: P, 43 pub(crate) phy: P,
44 pub(crate) station_management: EthernetStationManagement<T>, 44 pub(crate) station_management: EthernetStationManagement<T>,
45 pub(crate) mac_addr: [u8; 6], 45 pub(crate) mac_addr: [u8; 6],
46} 46}
47 47
48/// Pins of ethernet driver.
49enum Pins<'d> {
50 Rmii([PeripheralRef<'d, AnyPin>; 9]),
51 Mii([PeripheralRef<'d, AnyPin>; 14]),
52}
53
48macro_rules! config_pins { 54macro_rules! config_pins {
49 ($($pin:ident),*) => { 55 ($($pin:ident),*) => {
50 critical_section::with(|_| { 56 critical_section::with(|_| {
@@ -57,11 +63,11 @@ macro_rules! config_pins {
57} 63}
58 64
59impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> { 65impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
60 /// Create a new Ethernet driver. 66 /// Create a new RMII ethernet driver using 9 pins.
61 pub fn new<const TX: usize, const RX: usize>( 67 pub fn new_rmii<const TX: usize, const RX: usize>(
62 queue: &'d mut PacketQueue<TX, RX>, 68 queue: &'d mut PacketQueue<TX, RX>,
63 peri: impl Peripheral<P = T> + 'd, 69 peri: impl Peripheral<P = T> + 'd,
64 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd, 70 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
65 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd, 71 ref_clk: impl Peripheral<P = impl RefClkPin<T>> + 'd,
66 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd, 72 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
67 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd, 73 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
@@ -74,8 +80,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
74 phy: P, 80 phy: P,
75 mac_addr: [u8; 6], 81 mac_addr: [u8; 6],
76 ) -> Self { 82 ) -> Self {
77 into_ref!(peri, ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
78
79 // Enable the necessary Clocks 83 // Enable the necessary Clocks
80 #[cfg(not(rcc_h5))] 84 #[cfg(not(rcc_h5))]
81 critical_section::with(|_| { 85 critical_section::with(|_| {
@@ -85,7 +89,6 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
85 w.set_eth1rxen(true); 89 w.set_eth1rxen(true);
86 }); 90 });
87 91
88 // RMII
89 crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b100)); 92 crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b100));
90 }); 93 });
91 94
@@ -99,14 +102,110 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
99 w.set_ethrxen(true); 102 w.set_ethrxen(true);
100 }); 103 });
101 104
102 // RMII
103 crate::pac::SYSCFG 105 crate::pac::SYSCFG
104 .pmcr() 106 .pmcr()
105 .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4)); 107 .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4));
106 }); 108 });
107 109
110 into_ref!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
108 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 111 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
109 112
113 let pins = Pins::Rmii([
114 ref_clk.map_into(),
115 mdio.map_into(),
116 mdc.map_into(),
117 crs.map_into(),
118 rx_d0.map_into(),
119 rx_d1.map_into(),
120 tx_d0.map_into(),
121 tx_d1.map_into(),
122 tx_en.map_into(),
123 ]);
124
125 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
126 }
127
128 /// Create a new MII ethernet driver using 14 pins.
129 pub fn new_mii<const TX: usize, const RX: usize>(
130 queue: &'d mut PacketQueue<TX, RX>,
131 peri: impl Peripheral<P = T> + 'd,
132 irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
133 rx_clk: impl Peripheral<P = impl RXClkPin<T>> + 'd,
134 tx_clk: impl Peripheral<P = impl TXClkPin<T>> + 'd,
135 mdio: impl Peripheral<P = impl MDIOPin<T>> + 'd,
136 mdc: impl Peripheral<P = impl MDCPin<T>> + 'd,
137 rxdv: impl Peripheral<P = impl RXDVPin<T>> + 'd,
138 rx_d0: impl Peripheral<P = impl RXD0Pin<T>> + 'd,
139 rx_d1: impl Peripheral<P = impl RXD1Pin<T>> + 'd,
140 rx_d2: impl Peripheral<P = impl RXD2Pin<T>> + 'd,
141 rx_d3: impl Peripheral<P = impl RXD3Pin<T>> + 'd,
142 tx_d0: impl Peripheral<P = impl TXD0Pin<T>> + 'd,
143 tx_d1: impl Peripheral<P = impl TXD1Pin<T>> + 'd,
144 tx_d2: impl Peripheral<P = impl TXD2Pin<T>> + 'd,
145 tx_d3: impl Peripheral<P = impl TXD3Pin<T>> + 'd,
146 tx_en: impl Peripheral<P = impl TXEnPin<T>> + 'd,
147 phy: P,
148 mac_addr: [u8; 6],
149 ) -> Self {
150 // Enable necessary clocks.
151 #[cfg(not(rcc_h5))]
152 critical_section::with(|_| {
153 crate::pac::RCC.ahb1enr().modify(|w| {
154 w.set_eth1macen(true);
155 w.set_eth1txen(true);
156 w.set_eth1rxen(true);
157 });
158
159 crate::pac::SYSCFG.pmcr().modify(|w| w.set_epis(0b000));
160 });
161
162 #[cfg(rcc_h5)]
163 critical_section::with(|_| {
164 crate::pac::RCC.apb3enr().modify(|w| w.set_sbsen(true));
165
166 crate::pac::RCC.ahb1enr().modify(|w| {
167 w.set_ethen(true);
168 w.set_ethtxen(true);
169 w.set_ethrxen(true);
170 });
171
172 // TODO: This is for RMII - what would MII need here?
173 crate::pac::SYSCFG
174 .pmcr()
175 .modify(|w| w.set_eth_sel_phy(crate::pac::syscfg::vals::EthSelPhy::B_0X4));
176 });
177
178 into_ref!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
179 config_pins!(rx_clk, tx_clk, mdio, mdc, rxdv, rx_d0, rx_d1, rx_d2, rx_d3, tx_d0, tx_d1, tx_d2, tx_d3, tx_en);
180
181 let pins = Pins::Mii([
182 rx_clk.map_into(),
183 tx_clk.map_into(),
184 mdio.map_into(),
185 mdc.map_into(),
186 rxdv.map_into(),
187 rx_d0.map_into(),
188 rx_d1.map_into(),
189 rx_d2.map_into(),
190 rx_d3.map_into(),
191 tx_d0.map_into(),
192 tx_d1.map_into(),
193 tx_d2.map_into(),
194 tx_d3.map_into(),
195 tx_en.map_into(),
196 ]);
197
198 Self::new_inner(queue, peri, irq, pins, phy, mac_addr)
199 }
200
201 fn new_inner<const TX: usize, const RX: usize>(
202 queue: &'d mut PacketQueue<TX, RX>,
203 peri: impl Peripheral<P = T> + 'd,
204 _irq: impl interrupt::typelevel::Binding<interrupt::typelevel::ETH, InterruptHandler> + 'd,
205 pins: Pins<'d>,
206 phy: P,
207 mac_addr: [u8; 6],
208 ) -> Self {
110 let dma = ETH.ethernet_dma(); 209 let dma = ETH.ethernet_dma();
111 let mac = ETH.ethernet_mac(); 210 let mac = ETH.ethernet_mac();
112 let mtl = ETH.ethernet_mtl(); 211 let mtl = ETH.ethernet_mtl();
@@ -182,24 +281,12 @@ impl<'d, T: Instance, P: PHY> Ethernet<'d, T, P> {
182 } 281 }
183 }; 282 };
184 283
185 let pins = [
186 ref_clk.map_into(),
187 mdio.map_into(),
188 mdc.map_into(),
189 crs.map_into(),
190 rx_d0.map_into(),
191 rx_d1.map_into(),
192 tx_d0.map_into(),
193 tx_d1.map_into(),
194 tx_en.map_into(),
195 ];
196
197 let mut this = Self { 284 let mut this = Self {
198 _peri: peri, 285 _peri: peri.into_ref(),
199 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf), 286 tx: TDesRing::new(&mut queue.tx_desc, &mut queue.tx_buf),
200 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf), 287 rx: RDesRing::new(&mut queue.rx_desc, &mut queue.rx_buf),
201 pins, 288 pins,
202 phy: phy, 289 phy,
203 station_management: EthernetStationManagement { 290 station_management: EthernetStationManagement {
204 peri: PhantomData, 291 peri: PhantomData,
205 clock_range: clock_range, 292 clock_range: clock_range,
@@ -302,7 +389,10 @@ impl<'d, T: Instance, P: PHY> Drop for Ethernet<'d, T, P> {
302 dma.dmacrx_cr().modify(|w| w.set_sr(false)); 389 dma.dmacrx_cr().modify(|w| w.set_sr(false));
303 390
304 critical_section::with(|_| { 391 critical_section::with(|_| {
305 for pin in self.pins.iter_mut() { 392 for pin in match self.pins {
393 Pins::Rmii(ref mut pins) => pins.iter_mut(),
394 Pins::Mii(ref mut pins) => pins.iter_mut(),
395 } {
306 pin.set_as_disconnected(); 396 pin.set_as_disconnected();
307 } 397 }
308 }) 398 })
diff --git a/examples/stm32f4/src/bin/eth.rs b/examples/stm32f4/src/bin/eth.rs
index 7f5c8fdb1..2933cfe3c 100644
--- a/examples/stm32f4/src/bin/eth.rs
+++ b/examples/stm32f4/src/bin/eth.rs
@@ -63,7 +63,7 @@ async fn main(spawner: Spawner) -> ! {
63 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 63 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
64 64
65 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); 65 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
66 let device = Ethernet::new( 66 let device = Ethernet::new_rmii(
67 PACKETS.init(PacketQueue::<16, 16>::new()), 67 PACKETS.init(PacketQueue::<16, 16>::new()),
68 p.ETH, 68 p.ETH,
69 Irqs, 69 Irqs,
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 5bff48197..85b5bd3e0 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! {
64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
65 65
66 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); 66 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
67 let device = Ethernet::new( 67 let device = Ethernet::new_rmii(
68 PACKETS.init(PacketQueue::<16, 16>::new()), 68 PACKETS.init(PacketQueue::<16, 16>::new()),
69 p.ETH, 69 p.ETH,
70 Irqs, 70 Irqs,
diff --git a/examples/stm32h5/src/bin/eth.rs b/examples/stm32h5/src/bin/eth.rs
index 2370656e6..79288877f 100644
--- a/examples/stm32h5/src/bin/eth.rs
+++ b/examples/stm32h5/src/bin/eth.rs
@@ -67,7 +67,7 @@ async fn main(spawner: Spawner) -> ! {
67 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 67 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
68 68
69 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); 69 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new();
70 let device = Ethernet::new( 70 let device = Ethernet::new_rmii(
71 PACKETS.init(PacketQueue::<4, 4>::new()), 71 PACKETS.init(PacketQueue::<4, 4>::new()),
72 p.ETH, 72 p.ETH,
73 Irqs, 73 Irqs,
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index cd9a27fcd..9abdcf3c0 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -64,7 +64,7 @@ async fn main(spawner: Spawner) -> ! {
64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 64 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
65 65
66 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new(); 66 static PACKETS: StaticCell<PacketQueue<4, 4>> = StaticCell::new();
67 let device = Ethernet::new( 67 let device = Ethernet::new_rmii(
68 PACKETS.init(PacketQueue::<4, 4>::new()), 68 PACKETS.init(PacketQueue::<4, 4>::new()),
69 p.ETH, 69 p.ETH,
70 Irqs, 70 Irqs,
diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs
index dcc6e36e2..c4da5776f 100644
--- a/examples/stm32h7/src/bin/eth_client.rs
+++ b/examples/stm32h7/src/bin/eth_client.rs
@@ -65,7 +65,7 @@ async fn main(spawner: Spawner) -> ! {
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; 65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66 66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); 67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68 let device = Ethernet::new( 68 let device = Ethernet::new_rmii(
69 PACKETS.init(PacketQueue::<16, 16>::new()), 69 PACKETS.init(PacketQueue::<16, 16>::new()),
70 p.ETH, 70 p.ETH,
71 Irqs, 71 Irqs,
diff --git a/examples/stm32h7/src/bin/eth_client_mii.rs b/examples/stm32h7/src/bin/eth_client_mii.rs
new file mode 100644
index 000000000..de6ea522a
--- /dev/null
+++ b/examples/stm32h7/src/bin/eth_client_mii.rs
@@ -0,0 +1,142 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_net::tcp::client::{TcpClient, TcpClientState};
7use embassy_net::{Stack, StackResources};
8use embassy_stm32::eth::generic_smi::GenericSMI;
9use embassy_stm32::eth::{Ethernet, PacketQueue};
10use embassy_stm32::peripherals::ETH;
11use embassy_stm32::rng::Rng;
12use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config};
13use embassy_time::Timer;
14use embedded_io_async::Write;
15use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect};
16use rand_core::RngCore;
17use static_cell::StaticCell;
18use {defmt_rtt as _, panic_probe as _};
19
20bind_interrupts!(struct Irqs {
21 ETH => eth::InterruptHandler;
22 RNG => rng::InterruptHandler<peripherals::RNG>;
23});
24
25type Device = Ethernet<'static, ETH, GenericSMI>;
26
27#[embassy_executor::task]
28async fn net_task(stack: &'static Stack<Device>) -> ! {
29 stack.run().await
30}
31
32#[embassy_executor::main]
33async fn main(spawner: Spawner) -> ! {
34 let mut config = Config::default();
35 {
36 use embassy_stm32::rcc::*;
37 config.rcc.hsi = Some(HSIPrescaler::DIV1);
38 config.rcc.csi = true;
39 config.rcc.hsi48 = Some(Default::default()); // needed for RNG
40 config.rcc.pll1 = Some(Pll {
41 source: PllSource::HSI,
42 prediv: PllPreDiv::DIV4,
43 mul: PllMul::MUL50,
44 divp: Some(PllDiv::DIV2),
45 divq: None,
46 divr: None,
47 });
48 config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz
49 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
50 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
51 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
52 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
53 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
54 config.rcc.voltage_scale = VoltageScale::Scale1;
55 }
56 let p = embassy_stm32::init(config);
57 info!("Hello World!");
58
59 // Generate random seed.
60 let mut rng = Rng::new(p.RNG, Irqs);
61 let mut seed = [0; 8];
62 rng.fill_bytes(&mut seed);
63 let seed = u64::from_le_bytes(seed);
64
65 let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF];
66
67 static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new();
68
69 let device = Ethernet::new_mii(
70 PACKETS.init(PacketQueue::<16, 16>::new()),
71 p.ETH,
72 Irqs,
73 p.PA1,
74 p.PC3,
75 p.PA2,
76 p.PC1,
77 p.PA7,
78 p.PC4,
79 p.PC5,
80 p.PB0,
81 p.PB1,
82 p.PG13,
83 p.PG12,
84 p.PC2,
85 p.PE2,
86 p.PG11,
87 GenericSMI::new(1),
88 mac_addr,
89 );
90 info!("Device created");
91
92 let config = embassy_net::Config::dhcpv4(Default::default());
93 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {
94 // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24),
95 // dns_servers: Vec::new(),
96 // gateway: Some(Ipv4Address::new(10, 42, 0, 1)),
97 //});
98
99 // Init network stack
100 static STACK: StaticCell<Stack<Device>> = StaticCell::new();
101 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
102 let stack = &*STACK.init(Stack::new(
103 device,
104 config,
105 RESOURCES.init(StackResources::<3>::new()),
106 seed,
107 ));
108
109 // Launch network task
110 unwrap!(spawner.spawn(net_task(stack)));
111
112 // Ensure DHCP configuration is up before trying connect
113 stack.wait_config_up().await;
114
115 info!("Network task initialized");
116
117 let state: TcpClientState<1, 1024, 1024> = TcpClientState::new();
118 let client = TcpClient::new(&stack, &state);
119
120 loop {
121 // You need to start a server on the host machine, for example: `nc -l 8000`
122 let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000));
123
124 info!("connecting...");
125 let r = client.connect(addr).await;
126 if let Err(e) = r {
127 info!("connect error: {:?}", e);
128 Timer::after_secs(1).await;
129 continue;
130 }
131 let mut connection = r.unwrap();
132 info!("connected!");
133 loop {
134 let r = connection.write_all(b"Hello\n").await;
135 if let Err(e) = r {
136 info!("write error: {:?}", e);
137 break;
138 }
139 Timer::after_secs(1).await;
140 }
141 }
142}
diff --git a/tests/stm32/src/bin/eth.rs b/tests/stm32/src/bin/eth.rs
index 7c02f0354..b244874e7 100644
--- a/tests/stm32/src/bin/eth.rs
+++ b/tests/stm32/src/bin/eth.rs
@@ -71,6 +71,7 @@ async fn main(spawner: Spawner) {
71 const PACKET_QUEUE_SIZE: usize = 4; 71 const PACKET_QUEUE_SIZE: usize = 4;
72 72
73 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new(); 73 static PACKETS: StaticCell<PacketQueue<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>> = StaticCell::new();
74 #[cfg(not(eth_v2))]
74 let device = Ethernet::new( 75 let device = Ethernet::new(
75 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()), 76 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()),
76 p.ETH, 77 p.ETH,
@@ -90,6 +91,26 @@ async fn main(spawner: Spawner) {
90 GenericSMI::new(0), 91 GenericSMI::new(0),
91 mac_addr, 92 mac_addr,
92 ); 93 );
94 #[cfg(eth_v2)]
95 let device = Ethernet::new_rmii(
96 PACKETS.init(PacketQueue::<PACKET_QUEUE_SIZE, PACKET_QUEUE_SIZE>::new()),
97 p.ETH,
98 Irqs,
99 p.PA1,
100 p.PA2,
101 p.PC1,
102 p.PA7,
103 p.PC4,
104 p.PC5,
105 p.PG13,
106 #[cfg(not(feature = "stm32h563zi"))]
107 p.PB13,
108 #[cfg(feature = "stm32h563zi")]
109 p.PB15,
110 p.PG11,
111 GenericSMI::new(0),
112 mac_addr,
113 );
93 114
94 let config = embassy_net::Config::dhcpv4(Default::default()); 115 let config = embassy_net::Config::dhcpv4(Default::default());
95 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { 116 //let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 {