use enc424j600::smoltcp_phy; use smoltcp::wire::{ EthernetAddress, IpAddress, IpCidr, Ipv6Cidr }; use smoltcp::iface::{NeighborCache, EthernetInterfaceBuilder, EthernetInterface}; use smoltcp::socket::{SocketSet, TcpSocket, TcpSocketBuffer}; use core::str; use core::fmt::Write; use smoltcp::time::Instant; use cortex_m_rt::exception; ///spi use stm32f1xx_hal::{ time::U32Ext, delay::Delay }; /// Timer use core::cell::RefCell; use cortex_m::interrupt::Mutex; use stm32f1xx_hal::{ time::MilliSeconds, timer::{Timer, Event as TimerEvent}, rcc::Clocks, stm32::SYST }; /// Rate in Hz const TIMER_RATE: u32 = 20; /// Interval duration in milliseconds const TIMER_DELTA: u32 = 1000 / TIMER_RATE; /// Elapsed time in milliseconds static TIMER_MS: Mutex> = Mutex::new(RefCell::new(0)); /// Setup SysTick exception fn timer_setup(syst: SYST, clocks: Clocks) { let timer = Timer::syst(syst, &clocks); timer.start_count_down(TIMER_RATE.hz()).listen(TimerEvent::Update); } /// SysTick exception (Timer) #[exception] fn SysTick() { cortex_m::interrupt::free(|cs| { *TIMER_MS.borrow(cs) .borrow_mut() += TIMER_DELTA; }); } /// Obtain current time in milliseconds pub fn timer_now() -> MilliSeconds { let ms = cortex_m::interrupt::free(|cs| { *TIMER_MS.borrow(cs) .borrow() }); ms.ms() } pub struct NetStorage { ip_addrs: [IpCidr; 1], neighbor_cache: [Option<(IpAddress, smoltcp::iface::Neighbor)>; 8], } static mut NET_STORE: NetStorage = NetStorage { // Placeholder for the real IP address, which is initialized at runtime. ip_addrs: [IpCidr::Ipv6( Ipv6Cidr::SOLICITED_NODE_PREFIX, )], neighbor_cache: [None; 8], }; pub fn ethernet_init ( spi_eth: SpiEth, delay: Delay, clocks: &Clocks ) // -> EthernetInterface> { // Init controller match spi_eth.reset(&mut delay) { Ok(_) => { // serial_tx.write_fmt(format_args!("Initializing Ethernet...\n")).unwrap(); } Err(_) => { panic!("Ethernet initialization failed!") } } // Read MAC let mut eth_mac_addr: [u8; 6] = [0; 6]; spi_eth.read_mac_addr(&mut eth_mac_addr); for i in 0..6 { let byte = eth_mac_addr[i]; match i { // 0 => { // serial_tx.write_fmt(format_args!("MAC Address = {:02x}-", byte)).unwrap(); // }, // 1..=4 => { // serial_tx.write_fmt(format_args!("{:02x}-", byte)).unwrap(); // }, // 5 => { // serial_tx.write_fmt(format_args!("{:02x}\n", byte)).unwrap(); // }, _ => () }; } // Init Rx/Tx buffers spi_eth.init_rxbuf(); spi_eth.init_txbuf(); // serial_tx.write_fmt(format_args!("Ethernet controller initialized\n")).unwrap(); // Init smoltcp interface let eth_iface = { let device = smoltcp_phy::SmoltcpDevice::new(spi_eth); let store = unsafe { &mut NET_STORE }; store.ip_addrs[0] = IpCidr::new(IpAddress::v4(192, 168, 1, 88), 24); let neighbor_cache = NeighborCache::new(&mut store.neighbor_cache[..]); EthernetInterfaceBuilder::new(device) .ethernet_addr(EthernetAddress(eth_mac_addr)) .neighbor_cache(neighbor_cache) .ip_addrs(&mut store.ip_addrs[..]) .finalize() }; // serial_tx.write_fmt(format_args!("Ethernet interface initialized\n")).unwrap(); // Setup SysTick after releasing SYST from Delay // Reference to stm32-eth:examples/ip.rs timer_setup(delay.free(), *clocks); // serial_tx.write_fmt(format_args!("Timer initialized\n")).unwrap(); // eth_iface let iface = eth_iface; let greet_socket = { static mut TCP_SERVER_RX_DATA: [u8; 256] = [0; 256]; static mut TCP_SERVER_TX_DATA: [u8; 256] = [0; 256]; let tcp_rx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_RX_DATA[..] }); let tcp_tx_buffer = TcpSocketBuffer::new(unsafe { &mut TCP_SERVER_TX_DATA[..] }); TcpSocket::new(tcp_rx_buffer, tcp_tx_buffer) }; let mut socket_set_entries = [None, None]; let mut socket_set = SocketSet::new(&mut socket_set_entries[..]); let greet_handle = socket_set.add(greet_socket); { let store = unsafe { &mut NET_STORE }; // serial_tx.write_fmt(format_args!("TCP sockets will listen at {}\n", store.ip_addrs[0].address())).unwrap(); } // Copied / modified from: // smoltcp:examples/loopback.rs, examples/server.rs; // stm32-eth:examples/ip.rs, // git.m-labs.hk/M-Labs/tnetplug loop { // Poll let now = timer_now().0; let instant = Instant::from_millis(now as i64); match iface.poll(&mut socket_set, instant) { Ok(_) => { }, Err(e) => { // serial_tx.write_fmt(format_args!("[{}] Poll error: {:?}\n", instant, e)).unwrap(); } } // Control the "greeting" socket (:4321) { let mut socket = socket_set.get::(greet_handle); if !socket.is_open() { // serial_tx.write_fmt(format_args!("[{}] Listening to port 4321 for greeting, please connect to the port\n", instant)).unwrap(); socket.listen(4321).unwrap(); // socket.set_timeout(Some(smoltcp::time::Duration::from_millis(10000))); } if socket.can_send() { let greeting = "Welcome to the server demo for STM32F103!"; write!(socket, "{}\n", greeting).unwrap(); // serial_tx.write_fmt(format_args!("[{}] Greeting sent, socket closed\n", instant)).unwrap(); socket.close(); } if socket.can_recv() { // serial_tx.write_fmt(format_args!("[{}] Received packet: {:?}\n", // instant, socket.recv(|buffer| {(buffer.len(), str::from_utf8(buffer).unwrap())}))).unwrap(); } } } } // pub fn ethernet_test // (mut iface: EthernetInterface>) // { // // Copied / modified from smoltcp: // // examples/loopback.rs // }