diff --git a/ci-tools/fpga-boss/src/ftdi_uart.rs b/ci-tools/fpga-boss/src/ftdi_uart.rs index 132c0a1cb0..1edb9fb480 100644 --- a/ci-tools/fpga-boss/src/ftdi_uart.rs +++ b/ci-tools/fpga-boss/src/ftdi_uart.rs @@ -1,6 +1,9 @@ // Licensed under the Apache-2.0 license -use std::io::{self, ErrorKind}; +use std::{ + io::{self, ErrorKind}, + time::Duration, +}; use libftdi1_sys::{ftdi_bits_type, ftdi_interface, ftdi_parity_type, ftdi_stopbits_type}; use std::cell::RefCell; @@ -22,6 +25,24 @@ pub struct FtdiUartReaderBlocking { pub struct FtdiUartWriter { ftdi: Rc>, } +impl FtdiUartWriter { + pub fn send_break(&self) -> anyhow::Result<()> { + const BREAK_TIME: Duration = Duration::from_micros(100); + + let mut ftdi = self.ftdi.borrow_mut(); + ftdi.set_bitmode(0x01, BitMode::BitBang)?; + ftdi.write_all_data(&[0x00])?; + std::thread::sleep(BREAK_TIME); + ftdi.set_bitmode(0x01, BitMode::Reset)?; + ftdi.set_baudrate(115200)?; + ftdi.set_line_property( + ftdi_bits_type::BITS_8, + ftdi_stopbits_type::STOP_BIT_1, + ftdi_parity_type::NONE, + )?; + Ok(()) + } +} pub fn open( port_path: UsbPortPath, diff --git a/ci-tools/fpga-boss/src/main.rs b/ci-tools/fpga-boss/src/main.rs index 7ac1787c8d..e199e1f887 100644 --- a/ci-tools/fpga-boss/src/main.rs +++ b/ci-tools/fpga-boss/src/main.rs @@ -251,6 +251,9 @@ fn main_impl() -> anyhow::Result<()> { let mut stdin_len = tty::read_stdin_nonblock(&mut stdin_buf)?; escaper.process(&mut stdin_buf, &mut stdin_len, |ch| match ch { b'q' | b'Q' => alive = false, + b'b' | b'B' => { + uart_tx.send_break().unwrap(); + } ch => println!( "Unknown escape sequence: Ctrl-T + {:?}", char::from_u32(ch.into()).unwrap_or('?')