diff --git a/src/main.rs b/src/main.rs index ee851e2..1302f0a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,6 +33,10 @@ mod timer; mod led; use led::Led; +/// Interval at which to sample the ADC input and broadcast to all +/// clients. +/// +/// This should be a multiple of the `TIMER_RATE`. const OUTPUT_INTERVAL: u32 = 1000; #[cfg(not(feature = "semihosting"))] @@ -55,6 +59,7 @@ fn init_log() { init(logger).expect("set logger"); } +/// Initialization and main loop #[entry] fn main() -> ! { init_log(); diff --git a/src/net.rs b/src/net.rs index d485c64..05933e2 100644 --- a/src/net.rs +++ b/src/net.rs @@ -21,8 +21,11 @@ static mut TX_RING: Option<[RingEntry; 2]> = None; // TODO: generate one from device id const SRC_MAC: [u8; 6] = [0x00, 0x00, 0xDE, 0xAD, 0xBE, 0xEF]; +/// Interrupt pending flag: set by the `ETH` interrupt handler, should +/// be cleared before polling the interface. static NET_PENDING: Mutex> = Mutex::new(RefCell::new(false)); +/// Run callback `f` with ethernet driver and TCP/IP stack pub fn run(nvic: &mut NVIC, ethernet_mac: ETHERNET_MAC, ethernet_dma: ETHERNET_DMA, f: F) where F: FnOnce(EthernetInterface<&mut stm32_eth::Eth<'static, 'static>>), @@ -33,12 +36,14 @@ where let tx_ring = unsafe { TX_RING.get_or_insert(Default::default()) }; + // Ethernet driver let mut eth_dev = Eth::new( ethernet_mac, ethernet_dma, &mut rx_ring[..], &mut tx_ring[..] ); eth_dev.enable_interrupt(nvic); + // IP stack let local_addr = IpAddress::v4(192, 168, 69, 3); let mut ip_addrs = [IpCidr::new(local_addr, 24)]; let mut neighbor_storage = [None; 16]; @@ -53,8 +58,8 @@ where f(iface); } -/// Wake up from `wfi()`, clear interrupt flags, -/// and TODO: set pending flag +/// Potentially wake up from `wfi()`, set the interrupt pending flag, +/// clear interrupt flags. #[interrupt] fn ETH() { cortex_m::interrupt::free(|cs| { @@ -66,11 +71,14 @@ fn ETH() { stm32_eth::eth_interrupt_handler(&p.ETHERNET_DMA); } +/// Has an interrupt occurred since last call to `clear_pending()`? pub fn is_pending(cs: &CriticalSection) -> bool { *NET_PENDING.borrow(cs) .borrow() } +/// Clear the interrupt pending flag before polling the interface for +/// data. pub fn clear_pending(cs: &CriticalSection) { *NET_PENDING.borrow(cs) .borrow_mut() = false; diff --git a/src/server.rs b/src/server.rs index 76f2266..b1080f8 100644 --- a/src/server.rs +++ b/src/server.rs @@ -8,6 +8,9 @@ use smoltcp::{ const TCP_PORT: u16 = 23; +/// Number of server sockets and therefore concurrent client +/// sessions. Many data structures in `Server::run()` correspond to +/// this const. const SOCKET_COUNT: usize = 8; const TCP_RX_BUFFER_SIZE: usize = 2048; @@ -105,6 +108,7 @@ impl<'a, 'b> Server<'a, 'b> { } } +/// Reusing the `fmt::Write` trait just for `write!()` convenience impl<'a, 's> fmt::Write for Server<'a, 's> { /// Write to all connected clients fn write_str(&mut self, slice: &str) -> fmt::Result { diff --git a/src/timer.rs b/src/timer.rs index 3592a79..98e3505 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -8,18 +8,20 @@ use stm32f4xx_hal::{ stm32::SYST, }; -/// rate in Hz +/// Rate in Hz const TIMER_RATE: u32 = 10; -/// interval duration in milliseconds +/// 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 pub fn setup(syst: SYST, clocks: Clocks) { let mut timer = Timer::syst(syst, TIMER_RATE.hz(), clocks); timer.listen(TimerEvent::TimeOut); } +/// SysTick exception (Timer) #[exception] fn SysTick() { cortex_m::interrupt::free(|cs| { @@ -28,6 +30,7 @@ fn SysTick() { }); } +/// Obtain current time in milliseconds pub fn now() -> MilliSeconds { let ms = cortex_m::interrupt::free(|cs| { *TIMER_MS.borrow(cs)