Update Eth Link Speed with the detected Speed

- adds support to Half/FullDuplexBase10T, HalfDuplexBase100Tx Eth Speed
- fix a bug which Kirdy requires link to up to enter main loop
This commit is contained in:
linuswck 2024-03-06 12:15:08 +08:00
parent a579e5c5d5
commit eff8adc184
2 changed files with 41 additions and 21 deletions

View File

@ -67,6 +67,8 @@ fn main() -> ! {
loop { loop {
wd.feed(); wd.feed();
net::net::eth_poll_and_update_link_speed();
match state { match state {
State::LoadFlashSettings => { State::LoadFlashSettings => {
// State Transition // State Transition

View File

@ -12,12 +12,12 @@ use smoltcp::{
}; };
use stm32_eth::{ use stm32_eth::{
Parts, EthPins, PartsIn, Parts, EthPins, PartsIn,
mac::Speed, mac::{Speed, EthernetMACWithMii},
dma::{ dma::{
TxRingEntry, RxRingEntry, EthernetDMA TxRingEntry, RxRingEntry, EthernetDMA
}}; }};
use stm32f4xx_hal::{ use stm32f4xx_hal::{
gpio::{gpioa::*, gpiob::*, gpioc::*, Alternate, Input}, gpio::{gpioa::*, gpiob::*, gpioc::*, Alternate, Input, Pin},
rcc::Clocks, rcc::Clocks,
interrupt, interrupt,
}; };
@ -52,6 +52,8 @@ pub struct ServerHandle {
socket_addr: (IpAddress, u16), socket_addr: (IpAddress, u16),
iface: EthInterface, iface: EthInterface,
dma: EthernetDMA<'static, 'static>, dma: EthernetDMA<'static, 'static>,
phy: EthernetPhy<EthernetMACWithMii<Pin<'A', 2, Alternate<11>>, Pin<'C', 1, Alternate<11>>>>,
link_was_up: bool,
} }
pub type EthernetPins = pub type EthernetPins =
EthPins<PA1<Input>, PA7<Input>, PB11<Input>, PB12<Input>, PB13<Input>, PC4<Input>, PC5<Input>>; EthPins<PA1<Input>, PA7<Input>, PB11<Input>, PB12<Input>, PB13<Input>, PC4<Input>, PC5<Input>>;
@ -155,14 +157,6 @@ impl ServerHandle {
socket.listen(socket_addr).ok(); socket.listen(socket_addr).ok();
iface.poll(Instant::from_millis(i64::from(sys_timer::now())), &mut &mut dma, &mut sockets); iface.poll(Instant::from_millis(i64::from(sys_timer::now())), &mut &mut dma, &mut sockets);
let server = ServerHandle {
socket_handle: tcp_handle,
socket_set: sockets,
socket_addr: socket_addr,
iface: iface,
dma: dma,
};
if let Ok(mut phy) = EthernetPhy::from_miim(mac, 0) { if let Ok(mut phy) = EthernetPhy::from_miim(mac, 0) {
info!( info!(
"Resetting PHY as an extra step. Type: {}", "Resetting PHY as an extra step. Type: {}",
@ -170,27 +164,40 @@ impl ServerHandle {
); );
phy.phy_init(); phy.phy_init();
while !phy.phy_link_up() {}
if let Some(speed) = phy.speed().map(|s| match s { let server = ServerHandle {
socket_handle: tcp_handle,
socket_set: sockets,
socket_addr: socket_addr,
iface: iface,
dma: dma,
phy: phy,
link_was_up: false,
};
unsafe {
SERVER_HANDLE = Some(server);
}
} else {
panic!("Ethernet Phy is not supported");
}
}
pub fn update_link_speed(&mut self) {
if !self.link_was_up & self.phy.phy_link_up() {
if let Some(speed) = self.phy.speed().map(|s| match s {
PhySpeed::HalfDuplexBase10T => Speed::HalfDuplexBase10T, PhySpeed::HalfDuplexBase10T => Speed::HalfDuplexBase10T,
PhySpeed::FullDuplexBase10T => Speed::FullDuplexBase10T, PhySpeed::FullDuplexBase10T => Speed::FullDuplexBase10T,
PhySpeed::HalfDuplexBase100Tx => Speed::HalfDuplexBase100Tx, PhySpeed::HalfDuplexBase100Tx => Speed::HalfDuplexBase100Tx,
PhySpeed::FullDuplexBase100Tx => Speed::FullDuplexBase100Tx, PhySpeed::FullDuplexBase100Tx => Speed::FullDuplexBase100Tx,
}) { }) {
phy.get_miim().set_speed(speed); info!("New eth link is up. Setting detected PhySpeed: {:?}", speed);
info!("Detected link speed: {:?}", speed); self.phy.get_miim().set_speed(speed);
} else { } else {
debug!("Failed to detect link speed."); debug!("Failed to detect link speed.");
} }
} else {
info!("Not resetting unsupported PHY.");
}
unsafe {
SERVER_HANDLE = Some(server);
} }
self.link_was_up = self.phy.phy_link_up();
} }
pub fn recv(&mut self, buffer: &mut [u8])-> Result<usize, smoltcp::socket::tcp::RecvError> { pub fn recv(&mut self, buffer: &mut [u8])-> Result<usize, smoltcp::socket::tcp::RecvError> {
@ -332,6 +339,17 @@ impl<M: Miim> EthernetPhy<M> {
} }
} }
pub fn eth_poll_and_update_link_speed() {
unsafe {
if let Some(ref mut server_handle ) = SERVER_HANDLE {
server_handle.update_link_speed();
}
else {
panic!("eth_poll_and_update_link_speed is called before init");
}
}
}
pub fn eth_send(buffer: &mut [u8], num_bytes: usize) { pub fn eth_send(buffer: &mut [u8], num_bytes: usize) {
unsafe { unsafe {
if let Some(ref mut server_handle ) = SERVER_HANDLE { if let Some(ref mut server_handle ) = SERVER_HANDLE {