diff options
| -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.rs | 5 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v1.rs | 1 | ||||
| -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.rs | 8 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/eth.rs | 8 | ||||
| m--------- | stm32-data | 0 |
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 | ||
| 3 | use super::{StationManagement, PHY}; | 3 | use 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 | } |
| 44 | use self::phy_consts::*; | 36 | use self::phy_consts::*; |
| 45 | 37 | ||
| 46 | /// SMSC LAN8742A Ethernet PHY | 38 | /// Generic SMI Ethernet PHY |
| 47 | pub struct LAN8742A; | 39 | pub struct GenericSMI; |
| 48 | 40 | ||
| 49 | unsafe impl PHY for LAN8742A { | 41 | unsafe 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 |
| 95 | impl LAN8742A { | 78 | impl 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")] | ||
| 6 | mod _version; | 5 | mod _version; |
| 7 | pub mod lan8742a; | 6 | pub mod generic_smi; |
| 8 | 7 | ||
| 9 | pub use _version::*; | 8 | pub 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 | ||
| 13 | use crate::gpio::sealed::Pin as __GpioPin; | 13 | use crate::gpio::sealed::Pin as __GpioPin; |
| 14 | use crate::gpio::{sealed::AFType, AnyPin, Speed}; | 14 | use crate::gpio::{sealed::AFType, AnyPin, Speed}; |
| 15 | use crate::pac::{ETH, RCC, SYSCFG}; | 15 | #[cfg(eth_v1a)] |
| 16 | use crate::pac::AFIO; | ||
| 17 | #[cfg(any(eth_v1b, eth_v1c))] | ||
| 18 | use crate::pac::SYSCFG; | ||
| 19 | use crate::pac::{ETH, RCC}; | ||
| 16 | 20 | ||
| 17 | mod descriptors; | 21 | mod descriptors; |
| 18 | mod rx_desc; | 22 | mod 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)] | ||
| 50 | macro_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)] | ||
| 63 | macro_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))] | ||
| 45 | macro_rules! config_pins { | 76 | macro_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; | |||
| 11 | use embassy_net::{ | 11 | use embassy_net::{ |
| 12 | Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, | 12 | Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, |
| 13 | }; | 13 | }; |
| 14 | use embassy_stm32::eth::lan8742a::LAN8742A; | 14 | use embassy_stm32::eth::generic_smi::GenericSMI; |
| 15 | use embassy_stm32::eth::{Ethernet, State}; | 15 | use embassy_stm32::eth::{Ethernet, State}; |
| 16 | use embassy_stm32::interrupt; | 16 | use embassy_stm32::interrupt; |
| 17 | use embassy_stm32::peripherals::ETH; | 17 | use embassy_stm32::peripherals::ETH; |
| @@ -26,7 +26,7 @@ use panic_probe as _; | |||
| 26 | 26 | ||
| 27 | #[embassy::task] | 27 | #[embassy::task] |
| 28 | async fn main_task( | 28 | async 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 | ||
| 83 | static EXECUTOR: Forever<Executor> = Forever::new(); | 83 | static EXECUTOR: Forever<Executor> = Forever::new(); |
| 84 | static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); | 84 | static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); |
| 85 | static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new(); | 85 | static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new(); |
| 86 | static CONFIG: Forever<StaticConfigurator> = Forever::new(); | 86 | static CONFIG: Forever<StaticConfigurator> = Forever::new(); |
| 87 | static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); | 87 | static 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; | |||
| 14 | use embassy_net::{ | 14 | use embassy_net::{ |
| 15 | Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, | 15 | Config as NetConfig, Ipv4Address, Ipv4Cidr, StackResources, StaticConfigurator, TcpSocket, |
| 16 | }; | 16 | }; |
| 17 | use embassy_stm32::eth::lan8742a::LAN8742A; | 17 | use embassy_stm32::eth::generic_smi::GenericSMI; |
| 18 | use embassy_stm32::eth::{Ethernet, State}; | 18 | use embassy_stm32::eth::{Ethernet, State}; |
| 19 | use embassy_stm32::interrupt; | 19 | use embassy_stm32::interrupt; |
| 20 | use embassy_stm32::peripherals::ETH; | 20 | use embassy_stm32::peripherals::ETH; |
| @@ -26,7 +26,7 @@ use heapless::Vec; | |||
| 26 | 26 | ||
| 27 | #[embassy::task] | 27 | #[embassy::task] |
| 28 | async fn main_task( | 28 | async 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 | ||
| 83 | static EXECUTOR: Forever<Executor> = Forever::new(); | 83 | static EXECUTOR: Forever<Executor> = Forever::new(); |
| 84 | static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); | 84 | static STATE: Forever<State<'static, ETH, 4, 4>> = Forever::new(); |
| 85 | static ETH: Forever<Ethernet<'static, ETH, LAN8742A, 4, 4>> = Forever::new(); | 85 | static ETH: Forever<Ethernet<'static, ETH, GenericSMI, 4, 4>> = Forever::new(); |
| 86 | static CONFIG: Forever<StaticConfigurator> = Forever::new(); | 86 | static CONFIG: Forever<StaticConfigurator> = Forever::new(); |
| 87 | static NET_RESOURCES: Forever<StackResources<1, 2, 8>> = Forever::new(); | 87 | static 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 | ||
