Handle device disconnect

This commit is contained in:
hodasemi 2022-07-21 09:20:41 +02:00
parent f4adb2c7ee
commit 06f955e3d2
2 changed files with 58 additions and 32 deletions

View file

@ -8,15 +8,30 @@ use service_specific::*;
use shared::config::{Config, COMMAND_COUNT, COMMAND_PAUSE}; use shared::config::{Config, COMMAND_COUNT, COMMAND_PAUSE};
fn main() -> Result<()> { fn main() -> Result<()> {
// azdelivery usart device
// let usb_device = UsbId {
// vendor_id: 0x0403,
// product_id: 0x6001,
// };
// default arduino uno device
let usb_device = UsbId {
vendor_id: 0x2341,
product_id: 0x0043,
};
// create serial port // create serial port
let mut port = Port::open(SerialPortSettings { let mut port = Port::open(
baud_rate: 57600, usb_device,
data_bits: DataBits::Eight, SerialPortSettings {
parity: Parity::None, baud_rate: 57600,
stop_bits: StopBits::One, data_bits: DataBits::Eight,
flow_control: FlowControl::None, parity: Parity::None,
timeout: Duration::from_millis(2500), stop_bits: StopBits::One,
})?; flow_control: FlowControl::None,
timeout: Duration::from_millis(2500),
},
)?;
let mut message_builder = MessageBuilder::default(); let mut message_builder = MessageBuilder::default();
let mut button_infos = [Duration::default(); COMMAND_COUNT]; let mut button_infos = [Duration::default(); COMMAND_COUNT];
@ -24,28 +39,25 @@ fn main() -> Result<()> {
// loop forever // loop forever
loop { loop {
// check if port could be read // handle incoming message
if let Ok(r) = port.read() { match port.read()? {
// handle incoming message SerialReadResult::Message(msg) => {
match r { // create message out of stream
SerialReadResult::Message(msg) => { // discard remaining for now
// create message out of stream if let Some(_remaining) = message_builder.check(msg) {
// discard remaining for now debug_assert!(message_builder.is_complete());
if let Some(_remaining) = message_builder.check(msg) {
debug_assert!(message_builder.is_complete());
println!("{}", message_builder.message()); println!("{}", message_builder.message());
// if message can be parsed to a number, try to execute a command // if message can be parsed to a number, try to execute a command
if let Ok(index) = message_builder.message().parse() { if let Ok(index) = message_builder.message().parse() {
execute_button_press(index, start_time.elapsed(), &mut button_infos)?; execute_button_press(index, start_time.elapsed(), &mut button_infos)?;
}
message_builder = MessageBuilder::default();
} }
message_builder = MessageBuilder::default();
} }
SerialReadResult::Timeout => (),
} }
SerialReadResult::Timeout => (),
} }
} }
} }

View file

@ -19,13 +19,18 @@ pub struct SerialPortSettings {
pub timeout: Duration, pub timeout: Duration,
} }
pub struct UsbId {
pub vendor_id: u16,
pub product_id: u16,
}
pub struct Port { pub struct Port {
serial_port: Box<dyn SerialPort>, serial_port: Box<dyn SerialPort>,
} }
impl Port { impl Port {
pub fn open(settings: SerialPortSettings) -> Result<Self> { pub fn open(usb_device: UsbId, settings: SerialPortSettings) -> Result<Self> {
let port_path = Self::find_macroboard()?; let port_path = Self::loop_usb_devices(usb_device)?;
let port = serialport::new(port_path, settings.baud_rate) let port = serialport::new(port_path, settings.baud_rate)
.data_bits(settings.data_bits) .data_bits(settings.data_bits)
@ -61,20 +66,29 @@ impl Port {
Ok(()) Ok(())
} }
fn find_macroboard() -> Result<String> { fn loop_usb_devices(usb_device: UsbId) -> Result<String> {
loop {
if let Some(device) = Self::find_macroboard(&usb_device)? {
return Ok(device);
}
std::thread::sleep(Duration::from_secs(2));
}
}
fn find_macroboard(usb_device: &UsbId) -> Result<Option<String>> {
let available_ports = serialport::available_ports() let available_ports = serialport::available_ports()
.map_err(|err| anyhow!("error querying serial ports ( {})", err))?; .map_err(|err| anyhow!("error querying serial ports ( {})", err))?;
for available_port in available_ports.iter() { for available_port in available_ports.iter() {
if let serialport::SerialPortType::UsbPort(usb_info) = &available_port.port_type { if let serialport::SerialPortType::UsbPort(usb_info) = &available_port.port_type {
// check for the correct device // check for the correct device
// if usb_info.vid == 0x0403 && usb_info.pid == 0x6001 { if usb_info.vid == usb_device.vendor_id && usb_info.pid == usb_device.product_id {
if usb_info.vid == 0x2341 && usb_info.pid == 0x0043 { return Ok(Some(available_port.port_name.clone()));
return Ok(available_port.port_name.clone());
} }
} }
} }
return Err(anyhow!("macro board not found on usb bus".to_string())); return Ok(None);
} }
} }