From f92b2ba6f5b31d8186c83d3c24f582052729ec85 Mon Sep 17 00:00:00 2001 From: occheung Date: Fri, 28 Aug 2020 15:48:13 +0800 Subject: [PATCH] ethernet: add scpi to silent socket example --- Cargo.toml | 3 +- README.md | 5 ++ examples/ethernet.rs | 53 ++++++++++++-------- src/lib.rs | 1 + src/scpi.rs | 115 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+), 22 deletions(-) create mode 100644 src/scpi.rs diff --git a/Cargo.toml b/Cargo.toml index 6693209..136a45a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,12 @@ panic-halt = "0.2.0" cortex-m = "0.6.2" cortex-m-rt = "0.6.12" embedded-hal = "0.2.4" -stm32h7 = {version = "0.11.0"} stm32h7xx-hal = {version = "0.6.0", features = [ "stm32h743v", "rt", "unproven" ] } stm32h7-ethernet = { version = "0.2.0", features = [ "phy_lan8742a", "stm32h743v" ] } smoltcp = { version = "0.6.0", default-features = false, features = [ "ethernet", "proto-ipv4", "proto-ipv6", "socket-raw" ] } nb = "1.0.0" +scpi = {path = "../scpi-rs/scpi", version = "0.3.4"} +lexical-core = { version="0.7.1", features=["radix"], default-features=false } # Logging and Panicking panic-itm = "0.4.1" diff --git a/README.md b/README.md index 03801a9..54b519c 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,8 @@ Select a different gdb config file from ```gdb_config``` directory. set-gdb-config-file ``` Leave as blank for default openocd.gdb configuration. + +# Known problems + +This version does not compile on its own. +The SCPI crate referenced in ```cargo.toml``` refers a modified SCPI pasrsng crate stored locally. diff --git a/examples/ethernet.rs b/examples/ethernet.rs index 0474308..d7f0979 100644 --- a/examples/ethernet.rs +++ b/examples/ethernet.rs @@ -1,13 +1,13 @@ #![no_main] #![no_std] -//extern crate cortex_m_rt as rt; +// extern crate cortex_m_rt as rt; use core::sync::atomic::{AtomicU32, Ordering}; //#[macro_use] //extern crate log; -//extern crate cortex_m +// extern crate cortex_m; use panic_semihosting as _; use cortex_m; @@ -53,6 +53,8 @@ use smoltcp::socket::SocketSet; use smoltcp::socket::{SocketHandle, TcpSocket, TcpSocketBuffer}; use smoltcp::time::{Duration, Instant}; +use firmware::scpi::{MyDevice, TREE}; +use scpi::prelude::*; /// Configure SYSTICK for 1ms timebase fn systick_init(syst: &mut stm32::SYST, clocks: CoreClocks) { @@ -187,6 +189,17 @@ fn main() -> ! { .ip_addrs(&mut ip_addrs[..]) .finalize(); + // SCPI configs + let mut my_device = MyDevice {}; + + let mut errors = ArrayErrorQueue::<[Error; 10]>::new(); + let mut context = Context::new(&mut my_device, &mut errors, TREE); + + //Response bytebuffer + let mut buf = ArrayVecFormatter::<[u8; 256]>::new(); + + // SCPI configs END + // TODO: Need Iinitialize TCP socket storage? // Yes cannot into vectors let mut rx_storage = [0; BUFFER_SIZE]; @@ -254,16 +267,15 @@ fn main() -> ! { }; if socket.can_recv() && receive_and_not_send { - hprintln!("recv 6969"); let data = socket.recv(|buffer| { - counter += buffer.len(); (buffer.len(), buffer) - }); - hprintln!("{:?}", data); - receive_and_not_send = false; + }).unwrap(); + hprintln!("{:?}", data).unwrap(); + let result = lexical_core::parse_partial::(data).unwrap(); + writeln!(socket, "{}", (result.0 * 2.0)); } else if socket.can_recv() { - hprintln!("{:?}", socket.can_recv()); + // hprintln!("{:?}", socket.can_recv()); } if socket.can_send() && !receive_and_not_send { @@ -278,22 +290,21 @@ fn main() -> ! { socket.listen(7000).unwrap(); socket.set_timeout(Some(Duration::from_millis(1000000))); } - - if socket.is_active() && !silent_socket_active { - hprintln!("tcp:7000 connected").unwrap(); - } - else if !socket.is_active() && silent_socket_active { - hprintln!("tcp:7000 disconnected").unwrap(); - socket.close(); - } - // Update socket activeness - silent_socket_active = socket.is_active(); if socket.can_recv() { - hprintln!("{:?}", socket.recv(|buffer| { - (buffer.len(), str::from_utf8(buffer).unwrap()) - })).unwrap(); + // hprintln!("{:?}", socket.recv(|buffer| { + // (buffer.len(), str::from_utf8(buffer).unwrap()) + // })).unwrap(); + let result = context.run(socket.recv(|buffer| { + (buffer.len(), buffer) + }).unwrap(), &mut buf); + if let Err(err) = result { + writeln!(socket, "{}", str::from_utf8(err.get_message()).unwrap()); + } else { + write!(socket, "{}", str::from_utf8(buf.as_slice()).unwrap()); + //break; + } } } } diff --git a/src/lib.rs b/src/lib.rs index be9ce27..0beeb4e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,7 @@ use crate::spi_slave::Parts; pub mod config_register; pub mod attenuator; pub mod dds; +pub mod scpi; /* * Enum for structuring error diff --git a/src/scpi.rs b/src/scpi.rs new file mode 100644 index 0000000..ca991f3 --- /dev/null +++ b/src/scpi.rs @@ -0,0 +1,115 @@ +use scpi::error::Result; +use scpi::expression::numeric_list; +use scpi::expression::numeric_list::NumericList; +use scpi::format::{Arbitrary, Character}; +use scpi::prelude::*; +use scpi::NumericValues; + +use core::convert::{TryFrom, TryInto}; +use scpi::ieee488::commands::*; +use scpi::scpi::commands::*; +use scpi::{ + ieee488_cls, + ieee488_ese, + ieee488_esr, + ieee488_idn, + ieee488_opc, + ieee488_rst, + ieee488_sre, + ieee488_stb, + ieee488_tst, + ieee488_wai, + nquery, + //Helpers + qonly, + scpi_crate_version, + scpi_status, + scpi_system, + scpi_tree, +}; + +pub struct MyDevice; + +pub struct HelloWorldCommand {} +impl Command for HelloWorldCommand { + qonly!(); + + fn query( + &self, + _context: &mut Context, + _args: &mut Tokenizer, + response: &mut ResponseUnit, + ) -> Result<()> { + response.data(b"Hello world" as &[u8]).finish() + } +} + +impl Device for MyDevice { + fn cls(&mut self) -> Result<()> { + Ok(()) + } + + fn rst(&mut self) -> Result<()> { + Ok(()) + } +} + +pub const TREE: &Node = scpi_tree![ + // Create default IEEE488 mandated commands + ieee488_cls!(), + ieee488_ese!(), + ieee488_esr!(), + ieee488_idn!(b"manufacturer", b"model", b"serial", "0.1.2".as_bytes()), + ieee488_opc!(), + ieee488_rst!(), + ieee488_sre!(), + ieee488_stb!(), + ieee488_tst!(), + ieee488_wai!(), + // Create default SCPI mandated STATus subsystem + scpi_status!(), + // Create default SCPI mandated SYSTem subsystem + scpi_system!(), + // + scpi_crate_version!(), + //Test + Node { + name: b"ABORt", + handler: None, + optional: false, + sub: &[], + }, + Node { + name: b"INITiate", + handler: None, + optional: false, + sub: &[ + Node { + name: b"IMMediate", + handler: None, + optional: true, + sub: &[], + } + ], + }, + Node { + name: b"EXAMple", + optional: true, + handler: None, + sub: &[ + Node { + name: b"HELLO", + optional: false, + handler: None, + sub: &[ + Node { + name: b"WORLD", + optional: true, + handler: Some(&HelloWorldCommand {}), + sub: &[], + } + ], + }, + ], + } +]; \ No newline at end of file