Successful serial connection
This commit is contained in:
parent
f0bfc77504
commit
99df32a0b9
5 changed files with 117 additions and 37 deletions
|
@ -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
26
rust/serial_reader/.vscode/launch.json
vendored
Normal 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}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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 = "*"
|
||||||
|
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
Loading…
Reference in a new issue