ethernet: add scpi to silent socket example

This commit is contained in:
occheung 2020-08-28 15:48:13 +08:00
parent a4b9f7b4f2
commit f92b2ba6f5
5 changed files with 155 additions and 22 deletions

View File

@ -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"

View File

@ -44,3 +44,8 @@ Select a different gdb config file from ```gdb_config``` directory.
set-gdb-config-file <filename>
```
Leave <filename> 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.

View File

@ -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::<f32>(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;
}
}
}
}

View File

@ -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

115
src/scpi.rs Normal file
View File

@ -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: &[],
}
],
},
],
}
];