aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/eth/generic_smi.rs (renamed from embassy-stm32/src/eth/lan8742a.rs)29
-rw-r--r--embassy-stm32/src/eth/mod.rs5
-rw-r--r--embassy-stm32/src/eth/v1.rs1
-rw-r--r--embassy-stm32/src/eth/v1/descriptors.rs (renamed from embassy-stm32/src/eth/v1c/descriptors.rs)0
-rw-r--r--embassy-stm32/src/eth/v1/mod.rs (renamed from embassy-stm32/src/eth/v1c/mod.rs)56
-rw-r--r--embassy-stm32/src/eth/v1/rx_desc.rs (renamed from embassy-stm32/src/eth/v1c/rx_desc.rs)0
-rw-r--r--embassy-stm32/src/eth/v1/tx_desc.rs (renamed from embassy-stm32/src/eth/v1c/tx_desc.rs)0
-rw-r--r--examples/stm32f7/src/bin/eth.rs8
-rw-r--r--examples/stm32h7/src/bin/eth.rs8
m---------stm32-data0
10 files changed, 71 insertions, 36 deletions
diff --git a/embassy-stm32/src/eth/lan8742a.rs b/embassy-stm32/src/eth/generic_smi.rs
index 74d0ca5de..5a323bf5a 100644
--- a/embassy-stm32/src/eth/lan8742a.rs
+++ b/embassy-stm32/src/eth/generic_smi.rs
@@ -1,4 +1,4 @@
1//! SMSC LAN8742A Ethernet PHY 1//! Generic SMI Ethernet PHY
2 2
3use super::{StationManagement, PHY}; 3use super::{StationManagement, PHY};
4 4
@@ -13,7 +13,6 @@ mod phy_consts {
13 pub const PHY_REG_ANEXP: u8 = 0x06; 13 pub const PHY_REG_ANEXP: u8 = 0x06;
14 pub const PHY_REG_ANNPTX: u8 = 0x07; 14 pub const PHY_REG_ANNPTX: u8 = 0x07;
15 pub const PHY_REG_ANNPRX: u8 = 0x08; 15 pub const PHY_REG_ANNPRX: u8 = 0x08;
16 pub const PHY_REG_SSR: u8 = 0x1F; // Special Status Register
17 pub const PHY_REG_CTL: u8 = 0x0D; // Ethernet PHY Register Control 16 pub const PHY_REG_CTL: u8 = 0x0D; // Ethernet PHY Register Control
18 pub const PHY_REG_ADDAR: u8 = 0x0E; // Ethernet PHY Address or Data 17 pub const PHY_REG_ADDAR: u8 = 0x0E; // Ethernet PHY Address or Data
19 18
@@ -33,20 +32,13 @@ mod phy_consts {
33 pub const PHY_REG_BSR_UP: u16 = 1 << 2; 32 pub const PHY_REG_BSR_UP: u16 = 1 << 2;
34 pub const PHY_REG_BSR_FAULT: u16 = 1 << 4; 33 pub const PHY_REG_BSR_FAULT: u16 = 1 << 4;
35 pub const PHY_REG_BSR_ANDONE: u16 = 1 << 5; 34 pub const PHY_REG_BSR_ANDONE: u16 = 1 << 5;
36
37 pub const PHY_REG_SSR_ANDONE: u16 = 1 << 12;
38 pub const PHY_REG_SSR_SPEED: u16 = 0b111 << 2;
39 pub const PHY_REG_SSR_10BASE_HD: u16 = 0b001 << 2;
40 pub const PHY_REG_SSR_10BASE_FD: u16 = 0b101 << 2;
41 pub const PHY_REG_SSR_100BASE_HD: u16 = 0b010 << 2;
42 pub const PHY_REG_SSR_100BASE_FD: u16 = 0b110 << 2;
43} 35}
44use self::phy_consts::*; 36use self::phy_consts::*;
45 37
46/// SMSC LAN8742A Ethernet PHY 38/// Generic SMI Ethernet PHY
47pub struct LAN8742A; 39pub struct GenericSMI;
48 40
49unsafe impl PHY for LAN8742A { 41unsafe impl PHY for GenericSMI {
50 /// Reset PHY and wait for it to come out of reset. 42 /// Reset PHY and wait for it to come out of reset.
51 fn phy_reset<S: StationManagement>(sm: &mut S) { 43 fn phy_reset<S: StationManagement>(sm: &mut S) {
52 sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET); 44 sm.smi_write(PHY_REG_BCR, PHY_REG_BCR_RESET);
@@ -67,7 +59,6 @@ unsafe impl PHY for LAN8742A {
67 59
68 fn poll_link<S: StationManagement>(sm: &mut S) -> bool { 60 fn poll_link<S: StationManagement>(sm: &mut S) -> bool {
69 let bsr = sm.smi_read(PHY_REG_BSR); 61 let bsr = sm.smi_read(PHY_REG_BSR);
70 let ssr = sm.smi_read(PHY_REG_SSR);
71 62
72 // No link without autonegotiate 63 // No link without autonegotiate
73 if bsr & PHY_REG_BSR_ANDONE == 0 { 64 if bsr & PHY_REG_BSR_ANDONE == 0 {
@@ -77,22 +68,14 @@ unsafe impl PHY for LAN8742A {
77 if bsr & PHY_REG_BSR_UP == 0 { 68 if bsr & PHY_REG_BSR_UP == 0 {
78 return false; 69 return false;
79 } 70 }
80 // No link if autonegotiate incomplete
81 if ssr & PHY_REG_SSR_ANDONE == 0 {
82 return false;
83 }
84 // No link if other side isn't 100Mbps full duplex
85 if ssr & PHY_REG_SSR_SPEED != PHY_REG_SSR_100BASE_FD {
86 return false;
87 }
88 71
89 // Got link 72 // Got link
90 true 73 true
91 } 74 }
92} 75}
93 76
94/// Public functions for the LAN8742A 77/// Public functions for the PHY
95impl LAN8742A { 78impl GenericSMI {
96 // Writes a value to an extended PHY register in MMD address space 79 // Writes a value to an extended PHY register in MMD address space
97 fn smi_write_ext<S: StationManagement>(sm: &mut S, reg_addr: u16, reg_data: u16) { 80 fn smi_write_ext<S: StationManagement>(sm: &mut S, reg_addr: u16, reg_data: u16) {
98 sm.smi_write(PHY_REG_CTL, 0x0003); // set address 81 sm.smi_write(PHY_REG_CTL, 0x0003); // set address
diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs
index 1e304b789..28f0c178f 100644
--- a/embassy-stm32/src/eth/mod.rs
+++ b/embassy-stm32/src/eth/mod.rs
@@ -1,10 +1,9 @@
1#![macro_use] 1#![macro_use]
2 2
3#[cfg_attr(eth_v1c, path = "v1c/mod.rs")] 3#[cfg_attr(any(eth_v1a, eth_v1b, eth_v1c), path = "v1/mod.rs")]
4#[cfg_attr(eth_v2, path = "v2/mod.rs")] 4#[cfg_attr(eth_v2, path = "v2/mod.rs")]
5#[cfg_attr(eth_v1, path = "v1.rs")]
6mod _version; 5mod _version;
7pub mod lan8742a; 6pub mod generic_smi;
8 7
9pub use _version::*; 8pub use _version::*;
10 9
diff --git a/embassy-stm32/src/eth/v1.rs b/embassy-stm32/src/eth/v1.rs
deleted file mode 100644
index 8b1378917..000000000
--- a/embassy-stm32/src/eth/v1.rs
+++ /dev/null
@@ -1 +0,0 @@
1
diff --git a/embassy-stm32/src/eth/v1c/descriptors.rs b/embassy-stm32/src/eth/v1/descriptors.rs
index 25f21ce19..25f21ce19 100644
--- a/embassy-stm32/src/eth/v1c/descriptors.rs
+++ b/embassy-stm32/src/eth/v1/descriptors.rs
diff --git a/embassy-stm32/src/eth/v1c/mod.rs b/embassy-stm32/src/eth/v1/mod.rs
index 8abe2e172..f102f4314 100644
--- a/embassy-stm32/src/eth/v1c/mod.rs
+++ b/embassy-stm32/src/eth/v1/mod.rs
@@ -12,7 +12,11 @@ use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
12 12
13use crate::gpio::sealed::Pin as __GpioPin; 13use crate::gpio::sealed::Pin as __GpioPin;
14use crate::gpio::{sealed::AFType, AnyPin, Speed}; 14use crate::gpio::{sealed::AFType, AnyPin, Speed};
15use crate::pac::{ETH, RCC, SYSCFG}; 15#[cfg(eth_v1a)]
16use crate::pac::AFIO;
17#[cfg(any(eth_v1b, eth_v1c))]
18use crate::pac::SYSCFG;
19use crate::pac::{ETH, RCC};
16 20
17mod descriptors; 21mod descriptors;
18mod rx_desc; 22mod rx_desc;
@@ -42,6 +46,33 @@ pub struct Ethernet<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> {
42 mac_addr: [u8; 6], 46 mac_addr: [u8; 6],
43} 47}
44 48
49#[cfg(eth_v1a)]
50macro_rules! config_in_pins {
51 ($($pin:ident),*) => {
52 // NOTE(unsafe) Exclusive access to the registers
53 critical_section::with(|_| {
54 $(
55 // TODO properly create a set_as_input function
56 $pin.set_as_af($pin.af_num(), AFType::Input);
57 )*
58 })
59 }
60}
61
62#[cfg(eth_v1a)]
63macro_rules! config_af_pins {
64 ($($pin:ident),*) => {
65 // NOTE(unsafe) Exclusive access to the registers
66 critical_section::with(|_| {
67 $(
68 // We are lucky here, this configures to max speed (50MHz)
69 $pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
70 )*
71 })
72 };
73}
74
75#[cfg(any(eth_v1b, eth_v1c))]
45macro_rules! config_pins { 76macro_rules! config_pins {
46 ($($pin:ident),*) => { 77 ($($pin:ident),*) => {
47 // NOTE(unsafe) Exclusive access to the registers 78 // NOTE(unsafe) Exclusive access to the registers
@@ -77,6 +108,22 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
77 108
78 // Enable the necessary Clocks 109 // Enable the necessary Clocks
79 // NOTE(unsafe) We have exclusive access to the registers 110 // NOTE(unsafe) We have exclusive access to the registers
111 #[cfg(eth_v1a)]
112 critical_section::with(|_| {
113 RCC.apb2enr().modify(|w| w.set_afioen(true));
114
115 // Select RMII (Reduced Media Independent Interface)
116 // Must be done prior to enabling peripheral clock
117 AFIO.mapr().modify(|w| w.set_mii_rmii_sel(true));
118
119 RCC.ahbenr().modify(|w| {
120 w.set_ethen(true);
121 w.set_ethtxen(true);
122 w.set_ethrxen(true);
123 });
124 });
125
126 #[cfg(any(eth_v1b, eth_v1c))]
80 critical_section::with(|_| { 127 critical_section::with(|_| {
81 RCC.apb2enr().modify(|w| w.set_syscfgen(true)); 128 RCC.apb2enr().modify(|w| w.set_syscfgen(true));
82 RCC.ahb1enr().modify(|w| { 129 RCC.ahb1enr().modify(|w| {
@@ -89,6 +136,13 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, T,
89 SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true)); 136 SYSCFG.pmc().modify(|w| w.set_mii_rmii_sel(true));
90 }); 137 });
91 138
139 #[cfg(eth_v1a)]
140 {
141 config_in_pins!(ref_clk, rx_d0, rx_d1);
142 config_af_pins!(mdio, mdc, tx_d0, tx_d1, tx_en);
143 }
144
145 #[cfg(any(eth_v1b, eth_v1c))]
92 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en); 146 config_pins!(ref_clk, mdio, mdc, crs, rx_d0, rx_d1, tx_d0, tx_d1, tx_en);
93 147
94 // NOTE(unsafe) We are ourselves not leak-safe. 148 // NOTE(unsafe) We are ourselves not leak-safe.
diff --git a/embassy-stm32/src/eth/v1c/rx_desc.rs b/embassy-stm32/src/eth/v1/rx_desc.rs
index 6164f2975..6164f2975 100644
--- a/embassy-stm32/src/eth/v1c/rx_desc.rs
+++ b/embassy-stm32/src/eth/v1/rx_desc.rs
diff --git a/embassy-stm32/src/eth/v1c/tx_desc.rs b/embassy-stm32/src/eth/v1/tx_desc.rs
index f253ab19a..f253ab19a 100644
--- a/embassy-stm32/src/eth/v1c/tx_desc.rs
+++ b/embassy-stm32/src/eth/v1/tx_desc.rs
diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs
index 446756c29..33e41de9c 100644
--- a/examples/stm32f7/src/bin/eth.rs
+++ b/examples/stm32f7/src/bin/eth.rs
@@ -11,7 +11,7 @@ use embassy::util::Forever;
11use embassy_net::{ 11use embassy_net::{
12 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, 12 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
13}; 13};
14use embassy_stm32::eth::lan8742a::LAN8742A; 14use embassy_stm32::eth::generic_smi::GenericSMI;
15use embassy_stm32::eth::{Ethernet, State}; 15use embassy_stm32::eth::{Ethernet, State};
16use embassy_stm32::interrupt; 16use embassy_stm32::interrupt;
17use embassy_stm32::peripherals::ETH; 17use embassy_stm32::peripherals::ETH;
@@ -26,7 +26,7 @@ use panic_probe as _;
26 26
27#[embassy::task] 27#[embassy::task]
28async fn main_task( 28async fn main_task(
29 device: &'static mut Ethernet<'static, ETH, LAN8742A, 4, 4>, 29 device: &'static mut Ethernet<'static, ETH, GenericSMI, 4, 4>,
30 config: &'static mut StaticConfigurator, 30 config: &'static mut StaticConfigurator,
31 spawner: Spawner, 31 spawner: Spawner,
32) { 32) {
@@ -82,7 +82,7 @@ static mut RNG_INST: Option<Rng<RNG>> = None;
82 82
83static EXECUTOR: Forever<Executor> = Forever::new(); 83static EXECUTOR: Forever<Executor> = Forever::new();
84static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); 84static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
85static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new(); 85static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new();
86static CONFIG: Forever<StaticConfigurator> = Forever::new(); 86static CONFIG: Forever<StaticConfigurator> = Forever::new();
87static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); 87static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();
88 88
@@ -112,7 +112,7 @@ fn main() -> ! {
112 let eth = unsafe { 112 let eth = unsafe {
113 ETH.put(Ethernet::new( 113 ETH.put(Ethernet::new(
114 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13, 114 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13,
115 p.PG11, LAN8742A, mac_addr, 0, 115 p.PG11, GenericSMI, mac_addr, 0,
116 )) 116 ))
117 }; 117 };
118 118
diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs
index 4eb5421a8..9a2e7a33d 100644
--- a/examples/stm32h7/src/bin/eth.rs
+++ b/examples/stm32h7/src/bin/eth.rs
@@ -14,7 +14,7 @@ use embassy::util::Forever;
14use embassy_net::{ 14use embassy_net::{
15 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, 15 Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket,
16}; 16};
17use embassy_stm32::eth::lan8742a::LAN8742A; 17use embassy_stm32::eth::generic_smi::GenericSMI;
18use embassy_stm32::eth::{Ethernet, State}; 18use embassy_stm32::eth::{Ethernet, State};
19use embassy_stm32::interrupt; 19use embassy_stm32::interrupt;
20use embassy_stm32::peripherals::ETH; 20use embassy_stm32::peripherals::ETH;
@@ -26,7 +26,7 @@ use heapless::Vec;
26 26
27#[embassy::task] 27#[embassy::task]
28async fn main_task( 28async fn main_task(
29 device: &'static mut Ethernet<'static, ETH, LAN8742A, 4, 4>, 29 device: &'static mut Ethernet<'static, ETH, GenericSMI, 4, 4>,
30 config: &'static mut StaticConfigurator, 30 config: &'static mut StaticConfigurator,
31 spawner: Spawner, 31 spawner: Spawner,
32) { 32) {
@@ -82,7 +82,7 @@ static mut RNG_INST: Option<Rng<RNG>> = None;
82 82
83static EXECUTOR: Forever<Executor> = Forever::new(); 83static EXECUTOR: Forever<Executor> = Forever::new();
84static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); 84static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new();
85static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new(); 85static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new();
86static CONFIG: Forever<StaticConfigurator> = Forever::new(); 86static CONFIG: Forever<StaticConfigurator> = Forever::new();
87static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); 87static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new();
88 88
@@ -114,7 +114,7 @@ fn main() -> ! {
114 let eth = unsafe { 114 let eth = unsafe {
115 ETH.put(Ethernet::new( 115 ETH.put(Ethernet::new(
116 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13, 116 state, p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13,
117 p.PG11, LAN8742A, mac_addr, 0, 117 p.PG11, GenericSMI, mac_addr, 0,
118 )) 118 ))
119 }; 119 };
120 120
diff --git a/stm32-data b/stm32-data
Subproject b71707e525e336f0afb9a74f3c436d3dd540ffc Subproject 9abfa9d2b51e6071fdc7e680b4a171e4fa20c2f