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};
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
let mut port = Port::open(SerialPortSettings {
baud_rate: 57600,
data_bits: DataBits::Eight,
parity: Parity::None,
stop_bits: StopBits::One,
flow_control: FlowControl::None,
timeout: Duration::from_millis(2500),
})?;
let mut port = Port::open(
usb_device,
SerialPortSettings {
baud_rate: 57600,
data_bits: DataBits::Eight,
parity: Parity::None,
stop_bits: StopBits::One,
flow_control: FlowControl::None,
timeout: Duration::from_millis(2500),
},
)?;
let mut message_builder = MessageBuilder::default();
let mut button_infos = [Duration::default(); COMMAND_COUNT];
@ -24,28 +39,25 @@ fn main() -> Result<()> {
// loop forever
loop {
// check if port could be read
if let Ok(r) = port.read() {
// handle incoming message
match r {
SerialReadResult::Message(msg) => {
// create message out of stream
// discard remaining for now
if let Some(_remaining) = message_builder.check(msg) {
debug_assert!(message_builder.is_complete());
// handle incoming message
match port.read()? {
SerialReadResult::Message(msg) => {
// create message out of stream
// discard remaining for now
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 let Ok(index) = message_builder.message().parse() {
execute_button_press(index, start_time.elapsed(), &mut button_infos)?;
}
message_builder = MessageBuilder::default();
// if message can be parsed to a number, try to execute a command
if let Ok(index) = message_builder.message().parse() {
execute_button_press(index, start_time.elapsed(), &mut button_infos)?;
}
message_builder = MessageBuilder::default();
}
SerialReadResult::Timeout => (),
}
SerialReadResult::Timeout => (),
}
}
}

View file

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