Successful serial connection

This commit is contained in:
hodasemi 2022-10-27 08:08:19 +02:00
parent f0bfc77504
commit 99df32a0b9
5 changed files with 117 additions and 37 deletions

View file

@ -74,33 +74,73 @@ fn main() -> ! {
)); ));
// Set up the USB Communications Class Device driver // Set up the USB Communications Class Device driver
let mut _serial = SerialPort::new(&usb_bus); let mut serial = SerialPort::new(&usb_bus);
// Create a USB device with a fake VID and PID // Create a USB device with a fake VID and PID
let mut _usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd)) let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x16c0, 0x27dd))
.manufacturer("Fake company") .manufacturer("Fake company")
.product("Serial port") .product("Serial port")
.serial_number("TEST") .serial_number("TEST")
.device_class(2) // from: https://www.usb.org/defined-class-codes .device_class(2) // from: https://www.usb.org/defined-class-codes
.build(); .build();
let mut i = 0;
loop { loop {
info!("start!"); info!("start!");
// delay.delay_ms(1000);
// serial.write("test".as_bytes()); // serial.write("test".as_bytes());
// serial_send(&mut serial, "test"); // serial_send(&mut serial, "test");
// delay.delay_ms(1000); // delay.delay_ms(1000);
i += 1;
if i == 100 {
i = 0;
serial_send(&mut serial, "test");
}
delay.delay_ms(8);
if usb_dev.poll(&mut [&mut serial]) {
// let mut buf = [0u8; 64];
// match serial.read(&mut buf) {
// Err(_e) => {
// // Do nothing
// }
// Ok(0) => {
// // Do nothing
// }
// Ok(count) => {
// // Convert to upper case
// buf.iter_mut().take(count).for_each(|b| {
// b.make_ascii_uppercase();
// });
// // Send back to the host
// let mut wr_ptr = &buf[..count];
// while !wr_ptr.is_empty() {
// match serial.write(wr_ptr) {
// Ok(len) => wr_ptr = &wr_ptr[len..],
// // On error, just drop unwritten data.
// // One possible error is Err(WouldBlock), meaning the USB
// // write buffer is full.
// Err(_) => break,
// };
// }
// }
// }
}
} }
} }
fn serial_send(serial: &mut SerialPort<UsbBus>, msg: &str) { fn serial_send(serial: &mut SerialPort<UsbBus>, msg: &str) {
let buf = [0u8; 64];
// Send back to the host // Send back to the host
let mut wr_ptr = &buf[..msg.len()]; let mut wr_ptr = msg.as_bytes();
while !wr_ptr.is_empty() { while !wr_ptr.is_empty() {
match serial.write(wr_ptr) { match serial.write(wr_ptr) {

26
rust/serial_reader/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'serial_reader'",
"cargo": {
"args": [
"build",
"--bin=serial_reader",
"--package=serial_reader"
],
"filter": {
"name": "serial_reader",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

View file

@ -9,3 +9,4 @@ edition = "2021"
serialport = "*" serialport = "*"
gtk = { version = "*", features = ["v3_24"] } gtk = { version = "*", features = ["v3_24"] }
anyhow = { version = "1.0", features = ["backtrace"] } anyhow = { version = "1.0", features = ["backtrace"] }
glib = "*"

View file

@ -1,24 +1,25 @@
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering::SeqCst; use std::sync::atomic::Ordering::SeqCst;
// use std::thread::JoinHandle;
use gtk::{prelude::*, TextView}; use gtk::{prelude::*, TextView};
use gtk::{Application, ApplicationWindow}; use gtk::{Application, ApplicationWindow};
use gtk::{Button, Entry, Orientation}; use gtk::{Button, Entry, Orientation};
use glib;
mod port; mod port;
use port::*; use port::*;
static CONNECTED: AtomicBool = AtomicBool::new(false); static CONNECTED: AtomicBool = AtomicBool::new(false);
// static mut THREAD: Option<JoinHandle<()>> = None; static mut PORT: Option<Port> = None;
fn main() { fn main() {
let app = Application::builder() let app = Application::builder()
.application_id("org.example.HelloWorld") .application_id("org.example.HelloWorld")
.build(); .build();
app.connect_activate(|app| { app.connect_activate(move |app| {
// We create the main window. // We create the main window.
let window = ApplicationWindow::builder() let window = ApplicationWindow::builder()
.application(app) .application(app)
@ -29,22 +30,39 @@ fn main() {
let master_box = gtk::Box::new(Orientation::Vertical, 5); let master_box = gtk::Box::new(Orientation::Vertical, 5);
let top_bar_box = gtk::Box::new(Orientation::Horizontal, 5); let top_bar_box = gtk::Box::new(Orientation::Horizontal, 5);
let pid = Entry::builder().text("0x27dd").editable(true).build(); let pid = Entry::builder().text("0x27dd").editable(true).build();
let vid = Entry::builder().text("0x16c0").editable(true).build(); let vid = Entry::builder().text("0x16c0").editable(true).build();
let connect_button = Button::with_label("Connect"); let connect_button = Button::with_label("Connect");
let serial_info = TextView::new();
top_bar_box.pack_end(&connect_button, true, true, 3); top_bar_box.pack_end(&connect_button, true, true, 3);
top_bar_box.pack_end(&vid, true, true, 3); top_bar_box.pack_end(&vid, true, true, 3);
top_bar_box.pack_end(&pid, true, true, 3); top_bar_box.pack_end(&pid, true, true, 3);
let serial_info = TextView::new();
master_box.pack_end(&serial_info, true, true, 3); master_box.pack_end(&serial_info, true, true, 3);
master_box.pack_end(&top_bar_box, false, true, 3); master_box.pack_end(&top_bar_box, false, true, 3);
window.add(&master_box); let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
std::thread::spawn(move || {
// loop forever
loop {
unsafe {
if let Some(port) = &mut PORT {
// handle incoming message
match port.read().unwrap() {
SerialReadResult::Message(msg) => {
if !msg.is_empty() {
tx.send(msg).unwrap();
}
}
SerialReadResult::UtfConversion(err) => println!("{:?}", err),
SerialReadResult::Timeout => (),
}
}
}
}
});
connect_button.connect_clicked(move |_| { connect_button.connect_clicked(move |_| {
if !CONNECTED.load(SeqCst) { if !CONNECTED.load(SeqCst) {
@ -62,7 +80,7 @@ fn main() {
}; };
let serialport_settings = SerialPortSettings { let serialport_settings = SerialPortSettings {
baud_rate: 57600, baud_rate: 9600,
data_bits: DataBits::Eight, data_bits: DataBits::Eight,
parity: Parity::None, parity: Parity::None,
stop_bits: StopBits::One, stop_bits: StopBits::One,
@ -70,32 +88,27 @@ fn main() {
timeout: Duration::from_millis(2500), timeout: Duration::from_millis(2500),
}; };
if let Ok(mut port) = Port::open(usb_id, serialport_settings) { if let Ok(port) = Port::open(usb_id, serialport_settings) {
CONNECTED.store(true, SeqCst); CONNECTED.store(true, SeqCst);
unsafe {
// unsafe { PORT = Some(port);
// THREAD = Some(std::thread::spawn(move || {
// loop forever
loop {
// handle incoming message
match port.read().unwrap() {
SerialReadResult::Message(msg) => {
let buffer = serial_info.buffer().unwrap();
buffer.insert(&mut buffer.end_iter(), &msg);
} }
SerialReadResult::UtfConversion(err) => println!("{:?}", err),
SerialReadResult::Timeout => (),
}
}
// }));
// }
} }
} }
}); });
let buffer = serial_info.buffer().unwrap();
rx.attach(None, move |message| {
if !message.is_empty() {
buffer.insert(&mut buffer.end_iter(), &format!("{}\n", message));
}
glib::Continue(true)
});
window.add(&master_box);
// Don't forget to make all widgets visible. // Don't forget to make all widgets visible.
window.show_all(); window.show_all();
}); });

View file

@ -48,7 +48,7 @@ impl Port {
#[allow(unused)] #[allow(unused)]
pub fn read(&mut self) -> Result<SerialReadResult> { pub fn read(&mut self) -> Result<SerialReadResult> {
let mut buf: Vec<u8> = (0..255).collect(); let mut buf: Vec<u8> = vec![0; 256];
match self.serial_port.read(&mut buf[..]) { match self.serial_port.read(&mut buf[..]) {
Ok(t) => match String::from_utf8(buf[0..t].to_vec()) { Ok(t) => match String::from_utf8(buf[0..t].to_vec()) {