forked from M-Labs/artiq
1
0
Fork 0

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.
This commit is contained in:
Chris Ballance 2018-07-30 23:43:19 +01:00 committed by Sébastien Bourdeauducq
parent 7d6a1b528d
commit 47740c8930
4 changed files with 57 additions and 17 deletions

View File

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

View File

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

View File

@ -32,7 +32,8 @@ pub fn read_magic<R>(reader: &mut R) -> Result<(), Error<R::ReadError>>
#[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()?
},

View File

@ -146,7 +146,8 @@ fn read_injection_status(channel: u32, probe: u8) -> u8 {
}
fn connection_worker(io: &Io, mut stream: &mut TcpStream) -> Result<(), Error<SchedError>> {
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<Sc
trace!("moninj<-host {:?}", request);
match request {
HostMessage::Monitor { enable, channel, probe } => {
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<Sc
}
if clock::get_ms() > 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<(), Error<Sc
*previous = Some(current);
}
}
for (&(channel, overrd), previous) in inject_watch_list.iter_mut() {
let current = read_injection_status(channel, overrd);
if previous.is_none() || previous.unwrap() != current {
let message = DeviceMessage::InjectionStatus {
channel: channel,
overrd: overrd,
value: current
};
trace!("moninj->host {:?}", message);
message.write_to(stream)?;
*previous = Some(current);
}
}
next_check = clock::get_ms() + 200;
}