diff --git a/src/main.rs b/src/main.rs index 419e7f7..a139f09 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,68 @@ -fn main() { - // It is necessary to call this function once. Otherwise, some patches to the runtime - // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 - esp_idf_svc::sys::link_patches(); +use std::ffi::CString; +use std::thread; +use std::time::Duration; - // Bind the log crate to the ESP Logging facilities +use esp_idf_svc::eth::{BlockingEth, EspEth, EthDriver, SpiEthChipset}; +use esp_idf_svc::eventloop::EspSystemEventLoop; +use esp_idf_svc::hal::peripherals::Peripherals; +use esp_idf_svc::hal::prelude::*; +use esp_idf_svc::hal::spi::{config::DriverConfig, Dma, SpiDriver}; +use esp_idf_svc::handle::RawHandle; // brings .handle() into scope for EspNetif +use log::info; + +fn main() -> anyhow::Result<()> { + esp_idf_svc::sys::link_patches(); esp_idf_svc::log::EspLogger::initialize_default(); - log::info!("Hello, world!"); + let peripherals = Peripherals::take()?; + let sysloop = EspSystemEventLoop::take()?; + let pins = peripherals.pins; + + let spi_driver = SpiDriver::new( + peripherals.spi2, + pins.gpio13, // SCLK + pins.gpio11, // MOSI + Some(pins.gpio12), // MISO + &DriverConfig { + dma: Dma::Auto(4096), // required — default (no DMA) can't move full ethernet frames + ..Default::default() + }, + )?; + + let eth_driver = EthDriver::new_spi( + spi_driver, + pins.gpio10, // INT + Some(pins.gpio14), // CS + Some(pins.gpio9), // RST + SpiEthChipset::W5500, + 20.MHz().into(), + Some(&[0x02, 0x00, 0x00, 0x12, 0x34, 0x56]), // locally-administered MAC + None, // default PHY address + sysloop.clone(), + )?; + + let eth = EspEth::wrap(eth_driver)?; + + // Set hostname BEFORE starting — esp-idf-svc's safe NetifConfiguration has no + // hostname field, so this goes through the raw ESP-IDF binding. It must happen + // before eth.start(), otherwise it won't be included in the DHCP request and + // your router/OS will show a generic name instead (max 32 bytes). + let hostname = CString::new("esp32-eth-device")?; + unsafe { + esp_idf_svc::sys::esp_netif_set_hostname(eth.netif().handle(), hostname.as_ptr()); + } + + let mut eth = BlockingEth::wrap(eth, sysloop)?; + + info!("Starting eth..."); + eth.start()?; + info!("Waiting for DHCP lease..."); + eth.wait_netif_up()?; + + let ip_info = eth.eth().netif().get_ip_info()?; + info!("Got IP: {:?}", ip_info); + + loop { + thread::sleep(Duration::from_secs(1)); + } }