diff --git a/Cargo.lock b/Cargo.lock index 28ab3dc..f4c420b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -881,15 +881,25 @@ dependencies = [ [[package]] name = "smoltcp" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe46639fd2ec79eadf8fe719f237a7a0bd4dac5d957f1ca5bbdbc1c3c39e53a" +checksum = "ab527c390c7e107f687bd92a886a083fde61b8cdc700b37f3d7e4346ffd8fae1" dependencies = [ "bitflags", "byteorder", "managed", ] +[[package]] +name = "smoltcp-nal" +version = "0.1.0" +source = "git+https://github.com/vertigo-designs/smoltcp-nal.git?branch=main#6a656dd78c5f7543475e95c0eaf81def95fc5a10" +dependencies = [ + "embedded-nal", + "heapless", + "smoltcp", +] + [[package]] name = "stabilizer" version = "0.4.1" @@ -912,7 +922,7 @@ dependencies = [ "panic-semihosting", "paste", "serde", - "smoltcp", + "smoltcp-nal", "stm32h7xx-hal", ] @@ -937,7 +947,7 @@ dependencies = [ [[package]] name = "stm32h7xx-hal" version = "0.8.0" -source = "git+https://github.com/stm32-rs/stm32h7xx-hal?branch=dma#3da22d4935c8f6e412b99e6662ec11da5265fb88" +source = "git+https://github.com/quartiq/stm32h7xx-hal?branch=rs/smoltcp-update#87a650664beab422b33f1e3d842f8d585ab5fdab" dependencies = [ "bare-metal 1.0.0", "cast", diff --git a/Cargo.toml b/Cargo.toml index 438e185..182d62b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,15 +52,14 @@ branch = "feature/mqtt-interface" [dependencies.mcp23017] git = "https://github.com/mrd0ll4r/mcp23017.git" -[dependencies.smoltcp] -version = "0.6" -features = ["ethernet", "proto-ipv4", "socket-tcp", "proto-ipv6"] -default-features = false +[dependencies.smoltcp-nal] +git = "https://github.com/vertigo-designs/smoltcp-nal.git" +branch = "main" [dependencies.stm32h7xx-hal] features = ["stm32h743v", "rt", "unproven", "ethernet", "quadspi"] -git = "https://github.com/stm32-rs/stm32h7xx-hal" -branch = "dma" +git = "https://github.com/quartiq/stm32h7xx-hal" +branch = "rs/smoltcp-update" [features] semihosting = ["panic-semihosting", "cortex-m-log/semihosting"] diff --git a/src/bin/dual-iir.rs b/src/bin/dual-iir.rs index 32a4b9e..ce084df 100644 --- a/src/bin/dual-iir.rs +++ b/src/bin/dual-iir.rs @@ -148,7 +148,7 @@ const APP: () = { let sleep = c .resources .mqtt_interface - .lock(|interface| interface.network_stack().update(time)); + .lock(|interface| !interface.network_stack().poll(time)); match c .resources diff --git a/src/bin/lockin.rs b/src/bin/lockin.rs index c226e3a..9575442 100644 --- a/src/bin/lockin.rs +++ b/src/bin/lockin.rs @@ -168,7 +168,7 @@ const APP: () = { time += 1; } - let sleep = c.resources.stack.update(time); + let sleep = !c.resources.stack.poll(time); if sleep { cortex_m::asm::wfi(); diff --git a/src/hardware/configuration.rs b/src/hardware/configuration.rs index 721c523..c2c8333 100644 --- a/src/hardware/configuration.rs +++ b/src/hardware/configuration.rs @@ -9,21 +9,32 @@ use crate::SAMPLE_BUFFER_SIZE; #[cfg(feature = "pounder_v1_1")] use core::convert::TryInto; -use smoltcp::{iface::Routes, wire::Ipv4Address}; - use stm32h7xx_hal::{ self as hal, ethernet::{self, PHY}, prelude::*, }; +use smoltcp_nal::smoltcp; + use embedded_hal::digital::v2::{InputPin, OutputPin}; use super::{ adc, afe, dac, design_parameters, digital_input_stamper, eeprom, pounder, - smoltcp_nal::NetStorage, timers, DdsOutput, NetworkStack, AFE0, AFE1, + timers, DdsOutput, NetworkStack, AFE0, AFE1, }; +pub struct NetStorage { + pub ip_addrs: [smoltcp::wire::IpCidr; 1], + pub sockets: [Option>; 1], + pub neighbor_cache: + [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], + pub routes_cache: + [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8], + pub tx_storage: [u8; 4096], + pub rx_storage: [u8; 4096], +} + /// The available networking devices on Stabilizer. pub struct NetworkDevices { pub stack: NetworkStack, @@ -510,8 +521,9 @@ pub fn setup( 24, ); - let default_v4_gw = Ipv4Address::new(10, 0, 16, 1); - let mut routes = Routes::new(&mut store.routes_cache[..]); + let default_v4_gw = smoltcp::wire::Ipv4Address::new(10, 0, 16, 1); + let mut routes = + smoltcp::iface::Routes::new(&mut store.routes_cache[..]); routes.add_default_ipv4_route(default_v4_gw).unwrap(); let neighbor_cache = @@ -553,7 +565,7 @@ pub fn setup( }; NetworkDevices { - stack: NetworkStack::new(interface, sockets), + stack: smoltcp_nal::NetworkStack::new(interface, sockets), phy: lan8742a, } }; diff --git a/src/hardware/mod.rs b/src/hardware/mod.rs index 97f8058..e1e6731 100644 --- a/src/hardware/mod.rs +++ b/src/hardware/mod.rs @@ -15,7 +15,6 @@ mod design_parameters; mod digital_input_stamper; mod eeprom; mod pounder; -mod smoltcp_nal; mod timers; pub use adc::{Adc0Input, Adc1Input}; @@ -36,16 +35,12 @@ pub type AFE1 = afe::ProgrammableGainAmplifier< hal::gpio::gpiod::PD15>, >; -// Type alias for the ethernet interface on Stabilizer. -pub type Ethernet = smoltcp::iface::EthernetInterface< - 'static, +pub type NetworkStack = smoltcp_nal::NetworkStack< 'static, 'static, hal::ethernet::EthernetDMA<'static>, >; -pub type NetworkStack = smoltcp_nal::NetworkStack<'static, 'static, 'static>; - pub use configuration::{setup, PounderDevices, StabilizerDevices}; #[inline(never)] diff --git a/src/hardware/smoltcp_nal.rs b/src/hardware/smoltcp_nal.rs deleted file mode 100644 index 9fd5420..0000000 --- a/src/hardware/smoltcp_nal.rs +++ /dev/null @@ -1,184 +0,0 @@ -use core::cell::RefCell; -///! Network abstraction layer for smoltcp. -use heapless::{consts, Vec}; -use miniconf::embedded_nal::{self as nal, nb}; - -use super::Ethernet; - -pub struct NetStorage { - pub ip_addrs: [smoltcp::wire::IpCidr; 1], - pub sockets: [Option>; 1], - pub neighbor_cache: - [Option<(smoltcp::wire::IpAddress, smoltcp::iface::Neighbor)>; 8], - pub routes_cache: - [Option<(smoltcp::wire::IpCidr, smoltcp::iface::Route)>; 8], - pub tx_storage: [u8; 4096], - pub rx_storage: [u8; 4096], -} - -#[derive(Debug)] -pub enum NetworkError { - NoSocket, - ConnectionFailure, - ReadFailure, - WriteFailure, - Unsupported, -} - -pub struct NetworkStack<'a, 'b, 'c> { - network_interface: RefCell, - sockets: RefCell>, - next_port: RefCell, - unused_handles: RefCell>, -} - -impl<'a, 'b, 'c> NetworkStack<'a, 'b, 'c> { - pub fn new( - interface: Ethernet, - sockets: smoltcp::socket::SocketSet<'a, 'b, 'c>, - ) -> Self { - let mut unused_handles: Vec< - smoltcp::socket::SocketHandle, - consts::U16, - > = Vec::new(); - for socket in sockets.iter() { - unused_handles.push(socket.handle()).unwrap(); - } - - NetworkStack { - network_interface: RefCell::new(interface), - sockets: RefCell::new(sockets), - next_port: RefCell::new(49152), - unused_handles: RefCell::new(unused_handles), - } - } - - pub fn update(&self, time: u32) -> bool { - match self.network_interface.borrow_mut().poll( - &mut self.sockets.borrow_mut(), - smoltcp::time::Instant::from_millis(time as i64), - ) { - Ok(changed) => changed == false, - Err(e) => { - info!("{:?}", e); - true - } - } - } - - fn get_ephemeral_port(&self) -> u16 { - // Get the next ephemeral port - let current_port = self.next_port.borrow().clone(); - - let (next, wrap) = self.next_port.borrow().overflowing_add(1); - *self.next_port.borrow_mut() = if wrap { 49152 } else { next }; - - return current_port; - } -} - -impl<'a, 'b, 'c> nal::TcpStack for NetworkStack<'a, 'b, 'c> { - type Error = NetworkError; - type TcpSocket = smoltcp::socket::SocketHandle; - - fn open( - &self, - _mode: nal::Mode, - ) -> Result { - match self.unused_handles.borrow_mut().pop() { - Some(handle) => { - // Abort any active connections on the handle. - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(handle); - internal_socket.abort(); - - Ok(handle) - } - None => Err(NetworkError::NoSocket), - } - } - - fn connect( - &self, - socket: smoltcp::socket::SocketHandle, - remote: nal::SocketAddr, - ) -> Result { - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(socket); - - // If we're already in the process of connecting, ignore the request silently. - if internal_socket.is_open() { - return Ok(socket); - } - - match remote.ip() { - nal::IpAddr::V4(addr) => { - let octets = addr.octets(); - let address = smoltcp::wire::Ipv4Address::new( - octets[0], octets[1], octets[2], octets[3], - ); - internal_socket - .connect( - (address, remote.port()), - self.get_ephemeral_port(), - ) - .map_err(|_| NetworkError::ConnectionFailure)?; - Ok(socket) - } - - // We only support IPv4. - _ => Err(NetworkError::Unsupported), - } - } - - fn is_connected( - &self, - socket: &smoltcp::socket::SocketHandle, - ) -> Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - Ok(socket.may_send() && socket.may_recv()) - } - - fn write( - &self, - socket: &mut smoltcp::socket::SocketHandle, - buffer: &[u8], - ) -> nb::Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - socket - .send_slice(buffer) - .map_err(|_| nb::Error::Other(NetworkError::WriteFailure)) - } - - fn read( - &self, - socket: &mut smoltcp::socket::SocketHandle, - buffer: &mut [u8], - ) -> nb::Result { - let mut sockets = self.sockets.borrow_mut(); - let socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(*socket); - socket - .recv_slice(buffer) - .map_err(|_| nb::Error::Other(NetworkError::ReadFailure)) - } - - fn close( - &self, - socket: smoltcp::socket::SocketHandle, - ) -> Result<(), NetworkError> { - let mut sockets = self.sockets.borrow_mut(); - let internal_socket: &mut smoltcp::socket::TcpSocket = - &mut *sockets.get(socket); - internal_socket.close(); - - self.unused_handles.borrow_mut().push(socket).unwrap(); - Ok(()) - } -}