Compare commits

..

No commits in common. "c740386d6bbb12feac4ab8df50883aa6c300ee83" and "4c88c31acace42bd6e399da355bd5d83289901c7" have entirely different histories.

2 changed files with 71 additions and 115 deletions

View File

@ -76,9 +76,8 @@ use firmware::{
cpld::{ cpld::{
CPLD, CPLD,
}, },
scpi::{ HelloWorldCommand, Channel1SwitchCommand}, scpi::{ HelloWorldCommand, Channel1SwitchCommand },
Urukul, Urukul,
scpi_root, recursive_scpi_tree
}; };
use scpi::prelude::*; use scpi::prelude::*;
use scpi::ieee488::commands::*; use scpi::ieee488::commands::*;
@ -100,6 +99,7 @@ use scpi::{
scpi_crate_version, scpi_crate_version,
scpi_status, scpi_status,
scpi_system, scpi_system,
scpi_tree,
}; };
/// Configure SYSTICK for 1ms timebase /// Configure SYSTICK for 1ms timebase
@ -295,10 +295,63 @@ fn main() -> ! {
.finalize(); .finalize();
// SCPI configs // SCPI configs
let tree = scpi_root!(
["EXAMple"] => {"HELLO" => {"WORLD" => HelloWorldCommand}}; // TODO: String for *idn? mandated command
"CHANNEL1" => {"SWitch" => Channel1SwitchCommand}
); // SCPI tree
let tree = 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"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: &[],
}
],
},
],
},
Node {
name: b"CHANNEL1",
optional: false,
handler: None,
sub: &[
Node {
name: b"SWitch",
optional: false,
handler: Some(&Channel1SwitchCommand {}),
sub: &[],
}
],
}
];
// Device was declared in prior // Device was declared in prior
let mut errors = ArrayErrorQueue::<[Error; 10]>::new(); let mut errors = ArrayErrorQueue::<[Error; 10]>::new();

View File

@ -6,7 +6,6 @@ use scpi::prelude::*;
use scpi::NumericValues; use scpi::NumericValues;
use core::convert::{TryFrom, TryInto}; use core::convert::{TryFrom, TryInto};
use core::str;
use scpi::ieee488::commands::*; use scpi::ieee488::commands::*;
use scpi::scpi::commands::*; use scpi::scpi::commands::*;
use scpi::{ use scpi::{
@ -26,6 +25,7 @@ use scpi::{
scpi_crate_version, scpi_crate_version,
scpi_status, scpi_status,
scpi_system, scpi_system,
scpi_tree,
}; };
use embedded_hal::blocking::spi::Transfer; use embedded_hal::blocking::spi::Transfer;
@ -33,89 +33,7 @@ use cortex_m_semihosting::hprintln;
use crate::{Urukul, UrukulTraits, Error as UrukulError}; use crate::{Urukul, UrukulTraits, Error as UrukulError};
#[macro_export] // pub struct MyDevice;
macro_rules! recursive_scpi_tree {
// Handle optional headers (end-node)
([$header_name: expr] => $handler: ident) => {
Node {
name: str::as_bytes($header_name),
handler: Some(&$handler{}),
sub: &[],
optional: true,
}
};
// Handle non-optinal header (end-node)
($header_name: expr => $handler: ident) => {
Node {
name: str::as_bytes($header_name),
handler: Some(&$handler{}),
sub: &[],
optional: false,
}
};
// Handle optional header with sub-commands
([$header_name: expr] => {$($($rest: tt)=>*);*}) => {
Node {
name: str::as_bytes($header_name),
handler: None,
sub: &[
$(
recursive_scpi_tree!($($rest)=>*),
)*
],
optional: true,
}
};
// Handle non-optional header with sub-commands
($header_name: expr => {$($($rest: tt)=>*);*}) => {
Node {
name: str::as_bytes($header_name),
handler: None,
sub: &[
$(
recursive_scpi_tree!($($rest)=>*),
)*
],
optional: false,
}
};
}
#[macro_export]
macro_rules! scpi_root {
($($($node: tt)=>*);*) => {
&Node {
name: b"ROOT",
optional: false,
handler: None,
sub: &[
// Create default IEEE488 mandated commands
ieee488_cls!(),
ieee488_ese!(),
ieee488_esr!(),
ieee488_idn!(b"manufacturer", b"model", b"serial", b"0.1.2"),
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!(),
$(
recursive_scpi_tree!($($node)=>*),
)*
]
}
};
}
pub struct HelloWorldCommand {} pub struct HelloWorldCommand {}
impl<T: Device> Command<T> for HelloWorldCommand { impl<T: Device> Command<T> for HelloWorldCommand {
@ -131,31 +49,7 @@ impl<T: Device> Command<T> for HelloWorldCommand {
} }
} }
macro_rules! declare_channel_commands { pub struct Channel1SwitchCommand {}
($($header: ident),*) => {
mashup! {
$(
m["channel0" $header] = Channel0 $header Command;
m["channel1" $header] = Channel1 $header Command;
m["channel2" $header] = Channel2 $header Command;
m["channel3" $header] = Channel3 $header Command;
)*
}
m! {
$(
pub struct "channel0" $header {}
pub struct "channel1" $header {}
pub struct "channel2" $header {}
pub struct "channel3" $header {}
)*
}
};
}
declare_channel_commands!(Switch);
// pub struct Channel1SwitchCommand {}
impl<T: Device + UrukulTraits> Command<T> for Channel1SwitchCommand { impl<T: Device + UrukulTraits> Command<T> for Channel1SwitchCommand {
nquery!(); nquery!();
@ -178,6 +72,15 @@ impl<T: Device + UrukulTraits> Command<T> for Channel1SwitchCommand {
} }
} }
// pub struct SwitchCnannelCommand {}
// impl<T: Device + UrukulTraits> Command<T> for SwitchChannelCommand {
// nquery!();
// fn event(&self, context: &mut Context<T>, args: &mut Tokenizer) -> Result<()> {
// }
// }
/* /*
* Implement "Device" trait from SCPI * Implement "Device" trait from SCPI
* TODO: Implement mandatory commands * TODO: Implement mandatory commands