-
Notifications
You must be signed in to change notification settings - Fork 935
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement MII interface with feature flag
Extend the eth/v2 module to support MII besides RMII and introduce feature flags for RMII/MII. Add eth_client_mii.rs example.
- Loading branch information
Showing
7 changed files
with
232 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
#![no_std] | ||
#![no_main] | ||
|
||
use defmt::*; | ||
use embassy_executor::Spawner; | ||
use embassy_net::tcp::client::{TcpClient, TcpClientState}; | ||
use embassy_net::{Stack, StackResources}; | ||
use embassy_stm32::eth::generic_smi::GenericSMI; | ||
use embassy_stm32::eth::{Ethernet, PacketQueue}; | ||
use embassy_stm32::peripherals::ETH; | ||
use embassy_stm32::rng::Rng; | ||
use embassy_stm32::{bind_interrupts, eth, peripherals, rng, Config}; | ||
use embassy_time::Timer; | ||
use embedded_io_async::Write; | ||
use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; | ||
use embassy_net::{Ipv4Address, Ipv4Cidr}; | ||
use rand_core::RngCore; | ||
use static_cell::StaticCell; | ||
use {defmt_rtt as _, panic_probe as _}; | ||
use heapless::Vec; | ||
|
||
bind_interrupts!(struct Irqs { | ||
ETH => eth::InterruptHandler; | ||
RNG => rng::InterruptHandler<peripherals::RNG>; | ||
}); | ||
|
||
type Device = Ethernet<'static, ETH, GenericSMI>; | ||
|
||
#[embassy_executor::task] | ||
async fn net_task(stack: &'static Stack<Device>) -> ! { | ||
stack.run().await | ||
} | ||
|
||
#[embassy_executor::main] | ||
async fn main(spawner: Spawner) -> ! { | ||
let mut config = Config::default(); | ||
{ | ||
use embassy_stm32::rcc::*; | ||
config.rcc.hsi = Some(HSIPrescaler::DIV1); | ||
config.rcc.csi = true; | ||
config.rcc.hsi48 = Some(Default::default()); // needed for RNG | ||
config.rcc.pll1 = Some(Pll { | ||
source: PllSource::HSI, | ||
prediv: PllPreDiv::DIV4, | ||
mul: PllMul::MUL50, | ||
divp: Some(PllDiv::DIV2), | ||
divq: None, | ||
divr: None, | ||
}); | ||
config.rcc.sys = Sysclk::PLL1_P; // 400 Mhz | ||
config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz | ||
config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz | ||
config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz | ||
config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz | ||
config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz | ||
config.rcc.voltage_scale = VoltageScale::Scale1; | ||
} | ||
let p = embassy_stm32::init(config); | ||
info!("Hello World!"); | ||
|
||
// Generate random seed. | ||
let mut rng = Rng::new(p.RNG, Irqs); | ||
let mut seed = [0; 8]; | ||
rng.fill_bytes(&mut seed); | ||
let seed = u64::from_le_bytes(seed); | ||
|
||
let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; | ||
|
||
static PACKETS: StaticCell<PacketQueue<16, 16>> = StaticCell::new(); | ||
|
||
// Note: You need to deactivate the `eth-rmii` and activate the `eth-mii` | ||
// feature. | ||
let device = Ethernet::new( | ||
PACKETS.init(PacketQueue::<16, 16>::new()), | ||
p.ETH, | ||
Irqs, | ||
p.PA1, | ||
p.PC3, | ||
p.PA2, | ||
p.PC1, | ||
p.PA7, | ||
p.PC4, | ||
p.PC5, | ||
p.PB0, | ||
p.PB1, | ||
p.PG13, | ||
p.PG12, | ||
p.PC2, | ||
p.PE2, | ||
p.PG11, | ||
GenericSMI::new(1), | ||
mac_addr, | ||
); | ||
info!("Device created"); | ||
|
||
// let config = embassy_net::Config::dhcpv4(Default::default()); | ||
let config = embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { | ||
address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 100, 5), 24), | ||
dns_servers: Vec::new(), | ||
gateway: Some(Ipv4Address::new(192, 168, 100, 1)), | ||
}); | ||
|
||
// Init network stack | ||
static STACK: StaticCell<Stack<Device>> = StaticCell::new(); | ||
static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new(); | ||
let stack = &*STACK.init(Stack::new( | ||
device, | ||
config, | ||
RESOURCES.init(StackResources::<3>::new()), | ||
seed, | ||
)); | ||
|
||
// Launch network task | ||
unwrap!(spawner.spawn(net_task(stack))); | ||
|
||
// Ensure DHCP configuration is up before trying connect | ||
// stack.wait_config_up().await; | ||
|
||
info!("Network task initialized"); | ||
|
||
let state: TcpClientState<1, 1024, 1024> = TcpClientState::new(); | ||
let client = TcpClient::new(&stack, &state); | ||
|
||
loop { | ||
// You need to start a server on the host machine, for example: `nc -l 8000` | ||
let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 100, 1), 8000)); | ||
|
||
info!("connecting..."); | ||
let r = client.connect(addr).await; | ||
if let Err(e) = r { | ||
info!("connect error: {:?}", e); | ||
Timer::after_secs(1).await; | ||
continue; | ||
} | ||
let mut connection = r.unwrap(); | ||
info!("connected!"); | ||
loop { | ||
let r = connection.write_all(b"Hello\n").await; | ||
if let Err(e) = r { | ||
info!("write error: {:?}", e); | ||
break; | ||
} | ||
Timer::after_secs(1).await; | ||
} | ||
} | ||
} |