use device_driver::{CommandInterface, CommandInterfaceBase, FieldsetMetadata};
pub struct DeviceInterface {
last_command: u8,
last_input: Vec<u8>,
}
impl CommandInterfaceBase for DeviceInterface {
type Error = ();
type AddressType = u8;
}
impl CommandInterface for DeviceInterface {
fn dispatch_command(
&mut self,
address: Self::AddressType,
input: &mut [u8],
_input_metadata: &FieldsetMetadata,
output: &mut [u8],
_output_metadata: &FieldsetMetadata,
) -> Result<(), Self::Error> {
self.last_command = address;
self.last_input = input.to_vec();
let len = output.len().min(input.len());
output[..len].copy_from_slice(&input[..len]);
Ok(())
}
}
device_driver::compile!(
unstable_ddsl: "
device MyTestDevice {
default-byte-order: LE,
command-address-type: u8,
default-access: RW,
/// A simple command
command Simple {
address: 0
},
/// A command with only inputs
command Input {
address: 1,
fields-in: fieldset InputFieldsIn {
size-bytes: 2,
/// The value!
field val 15:0 -> uint
}
},
/// A command with only outputs
command Output {
address: 2,
fields-out: fieldset OutputFieldsOut {
size-bytes: 1,
/// The value!
field val 7:0 -> uint
}
},
/// A command with inputs and outputs
command InOut {
address: 3,
fields-in: fieldset InOutFieldsIn {
size-bytes: 2,
/// The value!
field val 15:0 -> uint,
},
fields-out: fieldset InOutFieldsOut {
size-bytes: 1,
/// The value!
field val 7:0 -> uint
}
},
command repeated[4 stride 1] {
address: 4,
},
enum r {
a: _,
b: _,
},
command enum_repeated[r stride 2] {
address: 8,
}
}
"
);
#[test]
fn command_combinations() {
let mut device = MyTestDevice::new(DeviceInterface {
last_command: 0xFF,
last_input: Vec::new(),
});
device.simple().dispatch().unwrap();
assert_eq!(device.interface.last_command, 0);
assert_eq!(device.interface.last_input, vec![]);
device.input().dispatch_in(|reg| reg.set_val(123)).unwrap();
assert_eq!(device.interface.last_command, 1);
assert_eq!(device.interface.last_input, vec![0x7B, 0x00]);
let out = device.output().dispatch_out().unwrap();
assert_eq!(device.interface.last_command, 2);
assert_eq!(device.interface.last_input, vec![]);
assert_eq!(out.val(), 0);
let out = device
.in_out()
.dispatch_inout(|reg| reg.set_val(123))
.unwrap();
assert_eq!(device.interface.last_command, 3);
assert_eq!(device.interface.last_input, vec![0x7B, 0x00]);
assert_eq!(out.val(), 0x7B);
device.repeated().dispatch_at(3).unwrap();
assert_eq!(device.interface.last_command, 7);
assert_eq!(device.interface.last_input, vec![]);
device.enum_repeated().dispatch_at(R::A).unwrap();
assert_eq!(device.interface.last_command, 8);
assert_eq!(device.interface.last_input, vec![]);
}