#![no_std] #![no_main] #![feature(type_alias_impl_trait)] 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, State}; use embassy_stm32::peripherals::ETH; use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; use embedded_io::asynch::Write; use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; use rand_core::RngCore; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; static STATIC_CELL: StaticCell = StaticCell::new(); STATIC_CELL.init_with(move || $val) }}; } type Device = Ethernet<'static, ETH, GenericSMI, 4, 4>; #[embassy_executor::task] async fn net_task(stack: &'static Stack) -> ! { stack.run().await } #[embassy_executor::main] async fn main(spawner: Spawner) -> ! { let mut config = Config::default(); config.rcc.sys_ck = Some(mhz(400)); config.rcc.hclk = Some(mhz(200)); config.rcc.pll1.q_ck = Some(mhz(100)); let p = embassy_stm32::init(config); info!("Hello World!"); // Generate random seed. let mut rng = Rng::new(p.RNG); let mut seed = [0; 8]; rng.fill_bytes(&mut seed); let seed = u64::from_le_bytes(seed); let eth_int = interrupt::take!(ETH); let mac_addr = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; let device = unsafe { Ethernet::new( singleton!(State::new()), p.ETH, eth_int, p.PA1, p.PA2, p.PC1, p.PA7, p.PC4, p.PC5, p.PG13, p.PB13, p.PG11, GenericSMI, mac_addr, 0, ) }; let config = embassy_net::ConfigStrategy::Dhcp; //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config { // address: Ipv4Cidr::new(Ipv4Address::new(10, 42, 0, 61), 24), // dns_servers: Vec::new(), // gateway: Some(Ipv4Address::new(10, 42, 0, 1)), //}); // Init network stack let stack = &*singleton!(Stack::new( device, config, singleton!(StackResources::<1, 2, 8>::new()), seed )); // Launch network task unwrap!(spawner.spawn(net_task(&stack))); info!("Network task initialized"); // To ensure DHCP configuration before trying connect Timer::after(Duration::from_secs(20)).await; static STATE: TcpClientState<1, 1024, 1024> = TcpClientState::new(); let client = TcpClient::new(&stack, &STATE); loop { let addr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(10, 42, 0, 1), 8000)); info!("connecting..."); let r = client.connect(addr).await; if let Err(e) = r { info!("connect error: {:?}", e); Timer::after(Duration::from_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); return; } Timer::after(Duration::from_secs(1)).await; } } }