Send reset via software

This commit is contained in:
hodasemi 2022-11-18 15:33:19 +01:00
parent 5f41ee6bdf
commit d7243aff99
4 changed files with 66 additions and 50 deletions

View file

@ -20,6 +20,7 @@ use rp_pico as bsp;
use bsp::hal::{ use bsp::hal::{
clocks::{init_clocks_and_plls, Clock}, clocks::{init_clocks_and_plls, Clock},
pac, pac,
rom_data::reset_to_usb_boot,
sio::Sio, sio::Sio,
usb::UsbBus, usb::UsbBus,
watchdog::Watchdog, watchdog::Watchdog,
@ -30,7 +31,7 @@ use embedded_hal::adc::OneShot;
use usb_device::{class_prelude::*, prelude::*}; use usb_device::{class_prelude::*, prelude::*};
use crate::serial::Serial; use crate::serial::{Commands, Serial};
#[entry] #[entry]
fn main() -> ! { fn main() -> ! {
@ -119,36 +120,11 @@ fn main() -> ! {
delay.delay_ms(8); delay.delay_ms(8);
if usb_dev.poll(&mut [&mut serial]) { if usb_dev.poll(&mut [&mut serial]) {
if let Some(command) = serial.read() {
// let mut buf = [0u8; 64]; match command {
Commands::Reset => reset_to_usb_boot(0, 0),
// 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,
// };
// }
// }
// }
} }
} }
} }

View file

@ -7,16 +7,20 @@ use usbd_serial::SerialPort;
use numtoa::NumToA; use numtoa::NumToA;
pub enum Commands {
Reset,
}
pub struct Serial<'a> { pub struct Serial<'a> {
serial: SerialPort<'a, UsbBus>, serial: SerialPort<'a, UsbBus>,
buf: [u8; 20], buf: [u8; 256],
} }
impl<'a> Serial<'a> { impl<'a> Serial<'a> {
pub fn new(usb_bus: &'a UsbBusAllocator<UsbBus>) -> Self { pub fn new(usb_bus: &'a UsbBusAllocator<UsbBus>) -> Self {
Self { Self {
serial: SerialPort::new(&usb_bus), serial: SerialPort::new(&usb_bus),
buf: [0u8; 20], buf: [0u8; 256],
} }
} }
@ -36,6 +40,22 @@ impl<'a> Serial<'a> {
}; };
} }
} }
pub fn read(&mut self) -> Option<Commands> {
match self.serial.read(&mut self.buf) {
Err(_e) => None,
Ok(0) => None,
Ok(count) => {
let c = count.min(self.buf.len());
let msg = &self.buf[..c];
match msg {
b"reset" => Some(Commands::Reset),
_ => None,
}
}
}
}
} }
impl<'a> usb_device::class::UsbClass<rp_pico::hal::usb::UsbBus> for Serial<'a> { impl<'a> usb_device::class::UsbClass<rp_pico::hal::usb::UsbBus> for Serial<'a> {

View file

@ -1,5 +1,10 @@
use std::sync::atomic::AtomicBool; use std::{
use std::sync::atomic::Ordering::SeqCst; sync::{
atomic::{AtomicBool, Ordering::SeqCst},
Mutex,
},
thread,
};
use gtk::{prelude::*, PolicyType, TextView}; use gtk::{prelude::*, PolicyType, TextView};
use gtk::{Application, ApplicationWindow}; use gtk::{Application, ApplicationWindow};
@ -12,7 +17,7 @@ mod port;
use port::*; use port::*;
static CONNECTED: AtomicBool = AtomicBool::new(false); static CONNECTED: AtomicBool = AtomicBool::new(false);
static mut PORT: Option<Port> = None; static PORT: Mutex<Option<Port>> = Mutex::new(None);
fn main() { fn main() {
let app = Application::builder() let app = Application::builder()
@ -33,6 +38,7 @@ fn main() {
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 reset_button = Button::with_label("Reset");
let serial_info = TextView::new(); let serial_info = TextView::new();
let scrolled_window = ScrolledWindow::builder() let scrolled_window = ScrolledWindow::builder()
.vscrollbar_policy(PolicyType::Automatic) .vscrollbar_policy(PolicyType::Automatic)
@ -40,6 +46,7 @@ fn main() {
.build(); .build();
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(&reset_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);
@ -51,8 +58,9 @@ fn main() {
std::thread::spawn(move || { std::thread::spawn(move || {
// loop forever // loop forever
loop { loop {
unsafe { let mut port_lock = PORT.lock().unwrap();
if let Some(port) = &mut PORT {
if let Some(port) = &mut *port_lock {
// handle incoming message // handle incoming message
match port.read().unwrap() { match port.read().unwrap() {
SerialReadResult::Message(msg) => { SerialReadResult::Message(msg) => {
@ -64,7 +72,8 @@ fn main() {
SerialReadResult::Timeout => (), SerialReadResult::Timeout => (),
} }
} }
}
thread::sleep(Duration::from_millis(10));
} }
}); });
@ -95,10 +104,22 @@ fn main() {
if let Ok(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 { *PORT.lock().unwrap() = Some(port);
PORT = Some(port);
} }
} }
});
reset_button.connect_clicked(move |_| {
if CONNECTED.load(SeqCst) {
CONNECTED.store(false, SeqCst);
let mut port_lock = PORT.lock().unwrap();
if let Some(port) = &mut *port_lock {
port.write("reset").unwrap();
}
*port_lock = None;
} }
}); });

View file

@ -60,7 +60,6 @@ impl Port {
} }
} }
#[allow(unused)]
pub fn write(&mut self, msg: &str) -> Result<()> { pub fn write(&mut self, msg: &str) -> Result<()> {
self.serial_port self.serial_port
.write(msg.as_bytes()) .write(msg.as_bytes())