use std::io; use std::time::Duration; use crossbeam_channel::{select, Receiver, Sender}; use eframe::egui; use postcard::{from_bytes_cobs, to_stdvec_cobs}; use cheapsdo_protocol::*; #[derive(PartialEq, Debug)] pub enum Cmd { Disconnect, GetPLLSettings, SetPLLSetting(PLLSettings), } #[derive(PartialEq, Debug)] pub enum Data { DeviceState(StatusMessage), PLLSettings(PLLSettings), } pub fn poll_device(port: String, cmd_rx: Receiver, data_tx: Sender, ctx: egui::Context) { let mut port = serialport::new(port, 115_200) .timeout(Duration::from_millis(10)) .open() .expect("Failed to open port"); let get_pll_settings = HostMessage::GetPllSettings; let get_pll_settings_bytes = to_stdvec_cobs(&get_pll_settings).unwrap(); port.write_all(&get_pll_settings_bytes).unwrap(); let request_status = HostMessage::RequestStatus; let request_status_bytes = to_stdvec_cobs(&request_status).unwrap(); port.write_all(&request_status_bytes).unwrap(); loop { let mut serial_buf: Vec = vec![0; 128]; match port.read(serial_buf.as_mut_slice()) { Ok(t) => { serial_buf.truncate(t); println!("Data: {:?}", serial_buf); let dev_msg = from_bytes_cobs::(&mut serial_buf).unwrap(); match dev_msg { DeviceMessage::Status(status_msg) => { data_tx.send(Data::DeviceState(status_msg)).unwrap(); ctx.request_repaint(); } DeviceMessage::PLLSettings(settings) => { data_tx.send(Data::PLLSettings(settings)).unwrap(); ctx.request_repaint(); } } } Err(ref e) if e.kind() == io::ErrorKind::TimedOut => (), Err(e) => eprintln!("{:?}", e), } select! { recv(cmd_rx) -> cmd => match cmd { Ok(Cmd::Disconnect) => return, Ok(Cmd::GetPLLSettings) => { port.write_all(&get_pll_settings_bytes).unwrap(); } Ok(Cmd::SetPLLSetting(settings)) => { let set_settings = HostMessage::SetPLLSettings(settings); let set_settings_bytes = to_stdvec_cobs(&set_settings).unwrap(); port.write_all(&set_settings_bytes).unwrap(); } Err(_) => {}, }, default(Duration::from_secs(1)) => { port.write_all(&request_status_bytes).unwrap(); }, } } }