From 47740c89307846c491f7e7e6726195fbe55386ff Mon Sep 17 00:00:00 2001 From: Chris Ballance Date: Mon, 30 Jul 2018 23:43:19 +0100 Subject: [PATCH] share moninj injection state between dashboards Previously if one dashboard overrode a channel this was not visible on any other dashboard - the channel appeared to operate normally. --- artiq/coredevice/comm_moninj.py | 10 ++++-- artiq/dashboard/moninj.py | 17 +++++++--- artiq/firmware/libproto_artiq/moninj_proto.rs | 14 +++++--- artiq/firmware/runtime/moninj.rs | 33 ++++++++++++++++--- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/artiq/coredevice/comm_moninj.py b/artiq/coredevice/comm_moninj.py index 25fd11ba0..9397c97e5 100644 --- a/artiq/coredevice/comm_moninj.py +++ b/artiq/coredevice/comm_moninj.py @@ -51,16 +51,20 @@ class CommMonInj: del self._reader del self._writer - def monitor(self, enable, channel, probe): + def monitor_probe(self, enable, channel, probe): packet = struct.pack(">bblb", 0, enable, channel, probe) self._writer.write(packet) + def monitor_injection(self, enable, channel, overrd): + packet = struct.pack(">bblb", 1, enable, channel, overrd) + self._writer.write(packet) + def inject(self, channel, override, value): - packet = struct.pack(">blbb", 1, channel, override, value) + packet = struct.pack(">blbb", 2, channel, override, value) self._writer.write(packet) def get_injection_status(self, channel, override): - packet = struct.pack(">blb", 2, channel, override) + packet = struct.pack(">blb", 3, channel, override) self._writer.write(packet) async def _receive_cr(self): diff --git a/artiq/dashboard/moninj.py b/artiq/dashboard/moninj.py index d36807da3..bbd0b9a3e 100644 --- a/artiq/dashboard/moninj.py +++ b/artiq/dashboard/moninj.py @@ -339,18 +339,20 @@ class _DeviceManager: def setup_ttl_monitoring(self, enable, channel): if self.core_connection is not None: - self.core_connection.monitor(enable, channel, TTLProbe.level.value) - self.core_connection.monitor(enable, channel, TTLProbe.oe.value) + self.core_connection.monitor_probe(enable, channel, TTLProbe.level.value) + self.core_connection.monitor_probe(enable, channel, TTLProbe.oe.value) + self.core_connection.monitor_injection(enable, channel, TTLOverride.en.value) + self.core_connection.monitor_injection(enable, channel, TTLOverride.level.value) if enable: self.core_connection.get_injection_status(channel, TTLOverride.en.value) def setup_dds_monitoring(self, enable, bus_channel, channel): if self.core_connection is not None: - self.core_connection.monitor(enable, bus_channel, channel) + self.core_connection.monitor_probe(enable, bus_channel, channel) def setup_dac_monitoring(self, enable, spi_channel, channel): if self.core_connection is not None: - self.core_connection.monitor(enable, spi_channel, channel) + self.core_connection.monitor_probe(enable, spi_channel, channel) def monitor_cb(self, channel, probe, value): if channel in self.ttl_widgets: @@ -371,7 +373,12 @@ class _DeviceManager: def injection_status_cb(self, channel, override, value): if channel in self.ttl_widgets: - self.ttl_widgets[channel].cur_override = bool(value) + widget = self.ttl_widgets[channel] + if override == TTLOverride.en.value: + widget.cur_override = bool(value) + if override == TTLOverride.level.value: + widget.cur_level = bool(value) + widget.refresh_display() async def core_connector(self): while True: diff --git a/artiq/firmware/libproto_artiq/moninj_proto.rs b/artiq/firmware/libproto_artiq/moninj_proto.rs index d6f9a699b..283ecb0f3 100644 --- a/artiq/firmware/libproto_artiq/moninj_proto.rs +++ b/artiq/firmware/libproto_artiq/moninj_proto.rs @@ -32,7 +32,8 @@ pub fn read_magic(reader: &mut R) -> Result<(), Error> #[derive(Debug)] pub enum HostMessage { - Monitor { enable: bool, channel: u32, probe: u8 }, + MonitorProbe { enable: bool, channel: u32, probe: u8 }, + MonitorInjection { enable: bool, channel: u32, overrd: u8 }, Inject { channel: u32, overrd: u8, value: u8 }, GetInjectionStatus { channel: u32, overrd: u8 } } @@ -48,17 +49,22 @@ impl HostMessage { where R: Read + ?Sized { Ok(match reader.read_u8()? { - 0 => HostMessage::Monitor { + 0 => HostMessage::MonitorProbe { enable: if reader.read_u8()? == 0 { false } else { true }, channel: reader.read_u32()?, probe: reader.read_u8()? }, - 1 => HostMessage::Inject { + 1 => HostMessage::MonitorInjection { + enable: if reader.read_u8()? == 0 { false } else { true }, + channel: reader.read_u32()?, + overrd: reader.read_u8()? + }, + 2 => HostMessage::Inject { channel: reader.read_u32()?, overrd: reader.read_u8()?, value: reader.read_u8()? }, - 2 => HostMessage::GetInjectionStatus { + 3 => HostMessage::GetInjectionStatus { channel: reader.read_u32()?, overrd: reader.read_u8()? }, diff --git a/artiq/firmware/runtime/moninj.rs b/artiq/firmware/runtime/moninj.rs index d589d63d2..665927e39 100644 --- a/artiq/firmware/runtime/moninj.rs +++ b/artiq/firmware/runtime/moninj.rs @@ -146,7 +146,8 @@ fn read_injection_status(channel: u32, probe: u8) -> u8 { } fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error> { - let mut watch_list = BTreeMap::new(); + let mut probe_watch_list = BTreeMap::new(); + let mut inject_watch_list = BTreeMap::new(); let mut next_check = 0; read_magic(&mut stream)?; @@ -158,11 +159,18 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error { + HostMessage::MonitorProbe { enable, channel, probe } => { if enable { - let _ = watch_list.entry((channel, probe)).or_insert(None); + let _ = probe_watch_list.entry((channel, probe)).or_insert(None); } else { - let _ = watch_list.remove(&(channel, probe)); + let _ = probe_watch_list.remove(&(channel, probe)); + } + }, + HostMessage::MonitorInjection { enable, channel, overrd } => { + if enable { + let _ = inject_watch_list.entry((channel, overrd)).or_insert(None); + } else { + let _ = inject_watch_list.remove(&(channel, overrd)); } }, HostMessage::Inject { channel, overrd, value } => inject(channel, overrd, value), @@ -183,7 +191,7 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error next_check { - for (&(channel, probe), previous) in watch_list.iter_mut() { + for (&(channel, probe), previous) in probe_watch_list.iter_mut() { let current = read_probe(channel, probe); if previous.is_none() || previous.unwrap() != current { let message = DeviceMessage::MonitorStatus { @@ -198,6 +206,21 @@ fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Errorhost {:?}", message); + message.write_to(stream)?; + + *previous = Some(current); + } + } next_check = clock::get_ms() + 200; }