diff --git a/src/main.rs b/src/main.rs index 63375e0..9a198f4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -100,40 +100,42 @@ fn main() -> ! { timer::setup(cp.SYST, clocks); info!("Net startup"); - net::run(&mut cp.NVIC, dp.ETHERNET_MAC, dp.ETHERNET_DMA, |net| { - let mut server = Server::new(net); + net::run(&mut cp.NVIC, dp.ETHERNET_MAC, dp.ETHERNET_DMA, |iface| { + Server::run(iface, |server| { + let mut last_output = 0_u32; + loop { + led_green.on(); + let now = timer::now().0; + let instant = Instant::from_millis(now as i64); + server.poll(instant); + led_green.off(); - let mut last_output = 0_u32; - loop { - led_green.on(); - let now = timer::now().0; - let instant = Instant::from_millis(now as i64); - server.poll(instant); - led_green.off(); - - led_blue.on(); - let now = timer::now().0; - if now - last_output >= OUTPUT_INTERVAL { - let adc_value = adc_input::read(); - adc_value.map(|adc_value| { - write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap(); - }); - last_output = now; - } - led_blue.off(); - - // Update watchdog - wd.feed(); - - led_red.on(); - cortex_m::interrupt::free(|cs| { - if !net::is_pending(cs) { - // Wait for interrupts - wfi(); - net::clear_pending(cs); + led_blue.on(); + let now = timer::now().0; + if now - last_output >= OUTPUT_INTERVAL { + let adc_value = adc_input::read(); + adc_value.map(|adc_value| { + write!(server, "t={},pa3={}\r\n", now, adc_value).unwrap(); + }); + last_output = now; } - }); - led_red.off(); - } - }) + led_blue.off(); + + // Update watchdog + wd.feed(); + + led_red.on(); + cortex_m::interrupt::free(|cs| { + if !net::is_pending(cs) { + // Wait for interrupts + wfi(); + net::clear_pending(cs); + } + }); + led_red.off(); + } + }); + }); + + unimplemented!() } diff --git a/src/net.rs b/src/net.rs index 9196de2..d485c64 100644 --- a/src/net.rs +++ b/src/net.rs @@ -7,14 +7,15 @@ use bare_metal::CriticalSection; use stm32f4xx_hal::{ stm32::{interrupt, Peripherals, NVIC, ETHERNET_MAC, ETHERNET_DMA}, }; -use smoltcp::time::Instant; use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr}; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface}; -use smoltcp::socket::SocketSet; use stm32_eth::{Eth, RingEntry, RxDescriptor, TxDescriptor}; -// TODO: ram regions +/// Not on the stack so that stack can be placed in CCMRAM (which the +/// ethernet peripheral cannot access) static mut RX_RING: Option<[RingEntry; 8]> = None; +/// Not on the stack so that stack can be placed in CCMRAM (which the +/// ethernet peripheral cannot access) static mut TX_RING: Option<[RingEntry; 2]> = None; // TODO: generate one from device id @@ -22,9 +23,9 @@ const SRC_MAC: [u8; 6] = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; static NET_PENDING: Mutex> = Mutex::new(RefCell::new(false)); -pub fn run(nvic: &mut NVIC, ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA, f: F) -> ! +pub fn run(nvic: &mut NVIC, ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA, f: F) where - F: FnOnce(&mut NetInterface) -> ! + F: FnOnce(EthernetInterface<&mut stm32_eth::Eth<'static, 'static>>), { let rx_ring = unsafe { RX_RING.get_or_insert(Default::default()) @@ -49,37 +50,10 @@ where .neighbor_cache(neighbor_cache) .finalize(); - let mut sockets_storage = [None, None, None, None]; - let sockets = SocketSet::new(&mut sockets_storage[..]); - - let mut net_iface = NetInterface { - iface, - sockets, - }; - f(&mut net_iface); + f(iface); } -pub struct NetInterface<'a> { - iface: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, - sockets: SocketSet<'a, 'static, 'static>, -} - -impl<'a> NetInterface<'a> { - /// Passes the boolean that indicates any sockets change. - pub fn poll(&mut self, now: Instant) -> bool { - // TODO: clear pending flag - - self.iface.poll(&mut self.sockets, now) - .ok() - .unwrap_or(false) - } - - pub fn sockets(&mut self) -> &mut SocketSet<'a, 'static, 'static> { - &mut self.sockets - } -} - -/// Wwake up from `wfi()`, clear interrupt flags, +/// Wake up from `wfi()`, clear interrupt flags, /// and TODO: set pending flag #[interrupt] fn ETH() { diff --git a/src/server.rs b/src/server.rs index 991230b..5053087 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,63 +1,88 @@ use core::fmt; use core::mem::uninitialized; use smoltcp::{ - socket::{SocketHandle, TcpSocket, TcpSocketBuffer}, + iface::EthernetInterface, + socket::{SocketSet, SocketHandle, TcpSocket, TcpSocketBuffer}, time::Instant, }; -use crate::net::NetInterface; const TCP_PORT: u16 = 23; -const SOCKET_COUNT: usize = 4; -const SOCKET_BUFFER_SIZE: usize = 2048; -const SOCKET_BUFFERS_LENGTH: usize = 2 * SOCKET_COUNT * SOCKET_BUFFER_SIZE; +const SOCKET_COUNT: usize = 8; -static mut SOCKET_BUFFERS: [u8; SOCKET_BUFFERS_LENGTH] = [0u8; SOCKET_BUFFERS_LENGTH]; +const TCP_RX_BUFFER_SIZE: usize = 2048; +const TCP_TX_BUFFER_SIZE: usize = 2048; -fn get_socket_buffers(i: usize) -> (&'static mut [u8], &'static mut [u8]) { - let offset1 = 2 * i * SOCKET_BUFFER_SIZE; - let offset2 = offset1 + SOCKET_BUFFER_SIZE; - let offset3 = offset2 + SOCKET_BUFFER_SIZE; - unsafe { - (&mut SOCKET_BUFFERS[offset1..offset2], - &mut SOCKET_BUFFERS[offset2..offset3]) - } +macro_rules! create_socket_storage { + ($rx_storage:ident, $tx_storage:ident) => ( + let mut $rx_storage = [0; TCP_RX_BUFFER_SIZE]; + let mut $tx_storage = [0; TCP_TX_BUFFER_SIZE]; + ) +} + +macro_rules! create_socket { + ($set:ident, $rx_storage:ident, $tx_storage:ident, $target:expr) => ( + let tcp_rx_buffer = TcpSocketBuffer::new(&mut $rx_storage[..]); + let tcp_tx_buffer = TcpSocketBuffer::new(&mut $tx_storage[..]); + let tcp_socket = TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer); + $target = $set.add(tcp_socket); + ) } /// Contains a number of server sockets that get all sent the same /// data (through `fmt::Write`). -pub struct Server<'a, 's> { +pub struct Server<'a, 'b> { + net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, + sockets: SocketSet<'b, 'b, 'static>, handles: [SocketHandle; SOCKET_COUNT], - net: &'s mut NetInterface<'a>, } -impl<'a, 's> Server<'a, 's> { - pub fn new(net: &'s mut NetInterface<'a>) -> Self { +impl<'a, 'b> Server<'a, 'b> { + pub fn run(net: EthernetInterface<'a, 'a, 'a, &'a mut stm32_eth::Eth<'static, 'static>>, f: F) + where + F: FnOnce(&mut Server<'a, '_>), + { + create_socket_storage!(tcp_rx_storage0, tcp_tx_storage0); + create_socket_storage!(tcp_rx_storage1, tcp_tx_storage1); + create_socket_storage!(tcp_rx_storage2, tcp_tx_storage2); + create_socket_storage!(tcp_rx_storage3, tcp_tx_storage3); + create_socket_storage!(tcp_rx_storage4, tcp_tx_storage4); + create_socket_storage!(tcp_rx_storage5, tcp_tx_storage5); + create_socket_storage!(tcp_rx_storage6, tcp_tx_storage6); + create_socket_storage!(tcp_rx_storage7, tcp_tx_storage7); + + let mut sockets_storage = [ + None, None, None, None, + None, None, None, None + ]; + let mut sockets = SocketSet::new(&mut sockets_storage[..]); + let mut handles: [SocketHandle; SOCKET_COUNT] = unsafe { uninitialized() }; + create_socket!(sockets, tcp_rx_storage0, tcp_tx_storage0, handles[0]); + create_socket!(sockets, tcp_rx_storage1, tcp_tx_storage1, handles[1]); + create_socket!(sockets, tcp_rx_storage2, tcp_tx_storage2, handles[2]); + create_socket!(sockets, tcp_rx_storage3, tcp_tx_storage3, handles[3]); + create_socket!(sockets, tcp_rx_storage4, tcp_tx_storage4, handles[4]); + create_socket!(sockets, tcp_rx_storage5, tcp_tx_storage5, handles[5]); + create_socket!(sockets, tcp_rx_storage6, tcp_tx_storage6, handles[6]); + create_socket!(sockets, tcp_rx_storage7, tcp_tx_storage7, handles[7]); + let mut server = Server { - handles: unsafe { uninitialized() }, + handles, + sockets, net, }; - - for i in 0..SOCKET_COUNT { - let buffers = get_socket_buffers(i); - let server_socket = TcpSocket::new( - TcpSocketBuffer::new(&mut buffers.0[..]), - TcpSocketBuffer::new(&mut buffers.1[..]) - ); - server.handles[i] = server.net.sockets().add(server_socket); - } - - server + f(&mut server); } pub fn poll(&mut self, now: Instant) { - let activity = self.net.poll(now); + let activity = self.net.poll(&mut self.sockets, now) + .unwrap_or(true); if ! activity { return; } for handle in &self.handles { - let mut socket = self.net.sockets().get::(*handle); + let mut socket = self.sockets.get::(*handle); if ! socket.is_open() { socket.listen(TCP_PORT) .unwrap(); @@ -70,7 +95,7 @@ impl<'a, 's> fmt::Write for Server<'a, 's> { /// Write to all connected clients fn write_str(&mut self, slice: &str) -> fmt::Result { for handle in &self.handles { - let mut socket = self.net.sockets().get::(*handle); + let mut socket = self.sockets.get::(*handle); if socket.can_send() { // Ignore errors, proceed with next client let _ = socket.write_str(slice);