From 938d0da367f2f89661f594d5712db8b552035f2a Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Thu, 15 Feb 2024 09:45:58 +0100 Subject: [PATCH 1/6] feat: Remove raspberry feature --- .github/actions/package/action.yml | 4 +- .github/workflows/ci.yml | 20 ++----- .github/workflows/release.yml | 3 -- Cargo.lock | 10 ---- cargo-espflash/README.md | 6 --- espflash/Cargo.toml | 2 - espflash/README.md | 12 ----- espflash/src/cli/config.rs | 6 --- espflash/src/cli/mod.rs | 18 +------ espflash/src/error.rs | 17 ------ espflash/src/interface.rs | 85 +----------------------------- espflash/src/lib.rs | 19 ------- 12 files changed, 8 insertions(+), 194 deletions(-) diff --git a/.github/actions/package/action.yml b/.github/actions/package/action.yml index 241a8047..2a62d1f4 100644 --- a/.github/actions/package/action.yml +++ b/.github/actions/package/action.yml @@ -4,8 +4,6 @@ inputs: required: false github_token: required: true - features: - required: false target: required: true runs_on: @@ -22,7 +20,7 @@ runs: - name: Build shell: bash run: | - cargo build --release --all --target ${{ inputs.target }} ${{ inputs.features }} + cargo build --release --all --target ${{ inputs.target }} - name: Compress (Unix) if: ${{ inputs.runs_on != 'windows-2022' }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d7b7b9bb..e4d0f940 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,11 +43,9 @@ jobs: - os: "ubuntu-22.04" target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - os: "ubuntu-22.04" target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" runs-on: ${{ matrix.platform.os }} steps: @@ -59,7 +57,7 @@ jobs: arch: ${{ matrix.platform.arch }} target: ${{ matrix.platform.target }} - - run: cargo check ${{ matrix.platform.features }} + - run: cargo check check-lib: name: Check lib (${{ matrix.platform.target }}) @@ -71,10 +69,8 @@ jobs: arch: "x86_64" - target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" runs-on: ubuntu-22.04 steps: @@ -86,7 +82,7 @@ jobs: arch: ${{ matrix.platform.arch }} target: ${{ matrix.platform.target }} - - run: cargo check -p espflash --lib --no-default-features ${{ matrix.platform.features }} + - run: cargo check -p espflash --lib --no-default-features msrv: name: Check MSRV (${{ matrix.platform.target }}) @@ -98,10 +94,8 @@ jobs: arch: "x86_64" - target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" runs-on: ubuntu-22.04 steps: @@ -114,7 +108,7 @@ jobs: target: ${{ matrix.platform.target }} toolchain: "1.73" - - run: cargo check ${{ matrix.platform.features }} + - run: cargo check # -------------------------------------------------------------------------- # Test @@ -129,10 +123,8 @@ jobs: arch: "x86_64" - target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" runs-on: ubuntu-22.04 steps: @@ -144,7 +136,7 @@ jobs: arch: ${{ matrix.platform.arch }} target: ${{ matrix.platform.target }} - - run: cargo test --lib ${{ matrix.platform.features }} + - run: cargo test --lib # -------------------------------------------------------------------------- # Lint @@ -159,10 +151,8 @@ jobs: arch: "x86_64" - target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" runs-on: ubuntu-22.04 steps: @@ -175,7 +165,7 @@ jobs: target: ${{ matrix.platform.target }} components: clippy - - run: cargo clippy ${{ matrix.platform.features }} -- -D warnings -A clippy::too_many_arguments + - run: cargo clippy -- -D warnings -A clippy::too_many_arguments rustfmt: name: Rustfmt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bd9f8770..8c4b8ea3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,11 +24,9 @@ jobs: - os: "ubuntu-20.04" target: "aarch64-unknown-linux-gnu" arch: "arm64" - features: "--features=raspberry" - os: "ubuntu-20.04" target: "armv7-unknown-linux-gnueabihf" arch: "armhf" - features: "--features=raspberry" # Windows - os: "windows-2022" target: "x86_64-pc-windows-msvc" @@ -50,7 +48,6 @@ jobs: with: arch: ${{ matrix.platform.arch }} github_token: ${{ secrets.GITHUB_TOKEN }} - features: ${{ matrix.platform.features }} target: ${{ matrix.platform.target }} runs_on: ${{ matrix.platform.os }} diff --git a/Cargo.lock b/Cargo.lock index 25315a25..734bf0ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1151,7 +1151,6 @@ dependencies = [ "miette", "parse_int", "regex", - "rppal", "serde", "serialport", "sha2", @@ -3342,15 +3341,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "rppal" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dc171bbe325b04172e18d917c58c2cf1fb5adfd9ffabb1d6b3d62ba4c1c1331" -dependencies = [ - "libc", -] - [[package]] name = "rustc-demangle" version = "0.1.23" diff --git a/cargo-espflash/README.md b/cargo-espflash/README.md index 06849054..4bb9bd3c 100644 --- a/cargo-espflash/README.md +++ b/cargo-espflash/README.md @@ -50,12 +50,6 @@ Alternatively, you can use [cargo-binstall] to download pre-compiled artifacts f cargo binstall cargo-espflash ``` -If you would like to flash from a Raspberry Pi using the built-in UART peripheral, you can enable the `raspberry` feature (note that this is not available if using [cargo-binstall]): - -```bash -cargo install cargo-espflash --features=raspberry -``` - By default, in Unix systems, we use the [`vendored-openssl` Cargo feature] which may require additional tools such as `perl` and `make`. To disable this feature, use: ``` diff --git a/espflash/Cargo.toml b/espflash/Cargo.toml index 57ead78f..164ec161 100644 --- a/espflash/Cargo.toml +++ b/espflash/Cargo.toml @@ -47,7 +47,6 @@ md-5 = "0.10.6" miette = { version = "7.0.0", features = ["fancy"] } parse_int = { version = "0.6.0", optional = true } regex = { version = "1.10.3", optional = true } -rppal = { version = "0.17.1", optional = true } serde = { version = "1.0.196", features = ["derive"] } serialport = { version = "4.3.0", optional = true } sha2 = "0.10.8" @@ -85,4 +84,3 @@ cli = [ ] serialport = ["dep:serialport"] -raspberry = ["dep:rppal"] diff --git a/espflash/README.md b/espflash/README.md index 360843c6..1d8eaabc 100644 --- a/espflash/README.md +++ b/espflash/README.md @@ -52,12 +52,6 @@ Alternatively, you can use [cargo-binstall] to download pre-compiled artifacts f cargo binstall espflash ``` -If you would like to flash from a Raspberry Pi using the built-in UART peripheral, you can enable the `raspberry` feature (note that this is not available if using [cargo-binstall]): - -```bash -cargo install espflash --features=raspberry -``` - [libuv]: https://libuv.org/ [cargo-binstall]: https://github.com/cargo-bins/cargo-binstall [releases]: https://github.com/esp-rs/espflash/releases @@ -129,12 +123,6 @@ or `cargo add espflash --no-default-features` We disable the `default-features` to opt-out the `cli` feature, which is enabled by default; you likely will not need any of these types or functions in your application so there’s no use pulling in the extra dependencies. -Just like when using `espflash` as an application, you can enable the raspberry feature to allow your dependent application to use the Raspberry Pi’s built-in UART: - -```toml -espflash = { version = "2.1", default-features = false, features = ["raspberry"] } -``` - ## Configuration File The configuration file allows you to define various parameters for your application: diff --git a/espflash/src/cli/config.rs b/espflash/src/cli/config.rs index 8c3c8e51..b5d3d2d9 100644 --- a/espflash/src/cli/config.rs +++ b/espflash/src/cli/config.rs @@ -26,12 +26,6 @@ use crate::error::Error; pub struct Connection { /// Name of the serial port used for communication pub serial: Option, - /// Data Transmit Ready pin - #[cfg(feature = "raspberry")] - pub dtr: Option, - /// Ready To Send pin - #[cfg(feature = "raspberry")] - pub rts: Option, } /// A configured, known USB device diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 536e34ef..87e3d665 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -68,14 +68,6 @@ pub struct ConnectArgs { /// Serial port connected to target device #[arg(short = 'p', long, env = "ESPFLASH_PORT")] pub port: Option, - /// DTR pin to use for the internal UART hardware. Uses BCM numbering. - #[cfg(feature = "raspberry")] - #[cfg_attr(feature = "raspberry", clap(long))] - pub dtr: Option, - /// RTS pin to use for the internal UART hardware. Uses BCM numbering. - #[cfg(feature = "raspberry")] - #[cfg_attr(feature = "raspberry", clap(long))] - pub rts: Option, } /// Generate completions for the given shell @@ -306,15 +298,7 @@ pub fn connect( info!("Serial port: '{}'", port_info.port_name); info!("Connecting..."); - #[cfg(feature = "raspberry")] - let (dtr, rts) = ( - args.dtr.or(config.connection.dtr), - args.rts.or(config.connection.rts), - ); - #[cfg(not(feature = "raspberry"))] - let (dtr, rts) = (None, None); - - let interface = Interface::new(&port_info, dtr, rts) + let interface = Interface::new(&port_info) .wrap_err_with(|| format!("Failed to open serial port {}", port_info.port_name))?; // NOTE: since `get_serial_port_info` filters out all PCI Port and Bluetooth diff --git a/espflash/src/error.rs b/espflash/src/error.rs index 4e727e85..35d4475e 100644 --- a/espflash/src/error.rs +++ b/espflash/src/error.rs @@ -12,8 +12,6 @@ use thiserror::Error; #[cfg(feature = "cli")] use crate::cli::monitor::parser::esp_defmt::DefmtError; -#[cfg(feature = "serialport")] -use crate::interface::SerialConfigError; use crate::{ command::CommandType, flasher::{FlashFrequency, FlashSize}, @@ -139,14 +137,6 @@ pub enum Error { )] StubRequired, - #[cfg(feature = "serialport")] - #[error("Incorrect serial port configuration")] - #[diagnostic( - code(espflash::serial_config), - help("Make sure you have specified the DTR signal if you are using an internal UART peripherial") - )] - SerialConfiguration(SerialConfigError), - #[error("The serial port '{0}' could not be found")] #[diagnostic( code(espflash::serial_not_found), @@ -243,13 +233,6 @@ impl From for Error { } } -#[cfg(feature = "serialport")] -impl From for Error { - fn from(err: SerialConfigError) -> Self { - Self::SerialConfiguration(err) - } -} - /// Connection-related errors #[derive(Debug, Diagnostic, Error)] #[non_exhaustive] diff --git a/espflash/src/interface.rs b/espflash/src/interface.rs index fbf92c90..77b0e552 100644 --- a/espflash/src/interface.rs +++ b/espflash/src/interface.rs @@ -1,16 +1,10 @@ //! Serial port wrapper to support platform-specific functionality -//! -//! Since we support flashing using a Raspberry Pi's built-in UART, we must be -//! able to abstract over the differences between this setup and when using a -//! serial port as one normally would, ie.) via USB. use std::io::Read; #[cfg(unix)] use std::os::fd::{AsRawFd, RawFd}; use miette::{Context, Result}; -#[cfg(feature = "raspberry")] -use rppal::gpio::{Gpio, OutputPin}; use serialport::{FlowControl, SerialPort, SerialPortInfo}; use crate::error::Error; @@ -20,39 +14,11 @@ type Port = serialport::TTYPort; #[cfg(windows)] type Port = serialport::COMPort; -/// Errors relating to the configuration of a serial port -#[derive(thiserror::Error, Debug)] -#[non_exhaustive] -pub enum SerialConfigError { - #[cfg(feature = "raspberry")] - #[error("You need to specify both DTR and RTS pins when using an internal UART peripheral")] - MissingDtrRtsForInternalUart, - #[cfg(feature = "raspberry")] - #[error("GPIO {0} is not available")] - GpioUnavailable(u8), -} - /// Wrapper around SerialPort where platform-specific modifications can be /// implemented. pub struct Interface { /// Hardware serial port used for communication pub serial_port: Port, - /// Data Transmit Ready pin - #[cfg(feature = "raspberry")] - pub dtr: Option, - /// Ready To Send pin - #[cfg(feature = "raspberry")] - pub rts: Option, -} - -/// Set the level of a GPIO -#[cfg(feature = "raspberry")] -fn write_gpio(gpio: &mut OutputPin, level: bool) { - if level { - gpio.set_high(); - } else { - gpio.set_low(); - } } /// Open a serial port @@ -65,44 +31,7 @@ fn open_port(port_info: &SerialPortInfo) -> Result { } impl Interface { - #[cfg(feature = "raspberry")] - pub fn new(port_info: &SerialPortInfo, dtr: Option, rts: Option) -> Result { - if port_info.port_type == serialport::SerialPortType::Unknown - && (dtr.is_none() || rts.is_none()) - { - // Assume internal UART, which has no DTR pin and usually no RTS either. - return Err(Error::from(SerialConfigError::MissingDtrRtsForInternalUart).into()); - } - - let gpios = Gpio::new().unwrap(); - - let rts = if let Some(gpio) = rts { - match gpios.get(gpio) { - Ok(pin) => Some(pin.into_output()), - Err(_) => return Err(Error::from(SerialConfigError::GpioUnavailable(gpio)).into()), - } - } else { - None - }; - - let dtr = if let Some(gpio) = dtr { - match gpios.get(gpio) { - Ok(pin) => Some(pin.into_output()), - Err(_) => return Err(Error::from(SerialConfigError::GpioUnavailable(gpio)).into()), - } - } else { - None - }; - - Ok(Self { - serial_port: open_port(port_info)?, - rts, - dtr, - }) - } - - #[cfg(not(feature = "raspberry"))] - pub fn new(port_info: &SerialPortInfo, _dtr: Option, _rts: Option) -> Result { + pub fn new(port_info: &SerialPortInfo) -> Result { Ok(Self { serial_port: open_port(port_info)?, }) @@ -110,23 +39,11 @@ impl Interface { /// Set the level of the DTR pin pub fn write_data_terminal_ready(&mut self, pin_state: bool) -> serialport::Result<()> { - #[cfg(feature = "raspberry")] - if let Some(gpio) = self.dtr.as_mut() { - write_gpio(gpio, pin_state); - return Ok(()); - } - self.serial_port.write_data_terminal_ready(pin_state) } /// Set the level of the RTS pin pub fn write_request_to_send(&mut self, pin_state: bool) -> serialport::Result<()> { - #[cfg(feature = "raspberry")] - if let Some(gpio) = self.rts.as_mut() { - write_gpio(gpio, pin_state); - return Ok(()); - } - self.serial_port.write_request_to_send(pin_state) } diff --git a/espflash/src/lib.rs b/espflash/src/lib.rs index 5c4bf52b..9306ea33 100644 --- a/espflash/src/lib.rs +++ b/espflash/src/lib.rs @@ -9,17 +9,6 @@ //! $ cargo binstall espflash //! ``` //! -//! Flashing via a Raspberry Pi's internal UART is also possible, however this -//! functionality is gated behind the `raspberry` feature; if you would like to -//! enable this simply enable the feature when installing: -//! -//! ```bash -//! $ cargo install espflash --feature=raspberry -//! ``` -//! -//! Note that this feature can only be enabled on a Raspberry Pi, as it depends -//! on the [rppal] package which will not build on most systems. -//! //! ## As a library //! //! [espflash] can also be used as a library: @@ -33,14 +22,6 @@ //! provide SemVer guarantees. You likely will not need any of these types or functions //! in your application so there's no use pulling in the extra dependencies. //! -//! Just like when using [espflash] as an application, you can enable the -//! `raspberry` feature to allow your dependent application to use the Raspberry -//! Pi's built-in UART: -//! -//! ```toml -//! espflash = { version = "2.1", default-features = false, features = ["raspberry"] } -//! ``` -//! //! [espflash]: https://crates.io/crates/espflash //! [cargo-binstall]: https://github.com/cargo-bins/cargo-binstall //! [rppal]: https://docs.rs/rppal/latest/rppal/ From 0b398fdf9e5c5c068888842cdba0041bb9b157ad Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 16 Feb 2024 10:50:01 +0100 Subject: [PATCH 2/6] feat: Initial changes to remove Interface mod --- espflash/src/bin/espflash.rs | 2 +- espflash/src/cli/mod.rs | 12 ++-- espflash/src/cli/monitor/mod.rs | 22 +++--- espflash/src/connection/mod.rs | 51 +++++++------- espflash/src/connection/reset.rs | 114 +++++++++++++++++++------------ espflash/src/flasher/mod.rs | 27 ++++---- 6 files changed, 126 insertions(+), 102 deletions(-) diff --git a/espflash/src/bin/espflash.rs b/espflash/src/bin/espflash.rs index 21902f04..830cd217 100644 --- a/espflash/src/bin/espflash.rs +++ b/espflash/src/bin/espflash.rs @@ -289,7 +289,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> { }; monitor( - flasher.into_interface(), + flasher.into_serial(), Some(&elf_data), pid, args.flash_args.monitor_baud.unwrap_or(default_baud), diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 87e3d665..2aabdc13 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -19,7 +19,7 @@ use esp_idf_part::{DataType, Partition, PartitionTable}; use indicatif::{style::ProgressStyle, HumanCount, ProgressBar}; use log::{debug, info, warn}; use miette::{IntoDiagnostic, Result, WrapErr}; -use serialport::{SerialPortType, UsbPortInfo}; +use serialport::{FlowControl, SerialPortType, UsbPortInfo}; use self::{ config::Config, @@ -34,7 +34,6 @@ use crate::{ parse_partition_table, FlashData, FlashFrequency, FlashMode, FlashSize, Flasher, ProgressCallbacks, }, - interface::Interface, targets::{Chip, XtalFrequency}, }; @@ -298,7 +297,10 @@ pub fn connect( info!("Serial port: '{}'", port_info.port_name); info!("Connecting..."); - let interface = Interface::new(&port_info) + let serial_port = serialport::new(&port_info.port_name, 115_200) + .flow_control(FlowControl::None) + .open_native() + .map_err(Error::from) .wrap_err_with(|| format!("Failed to open serial port {}", port_info.port_name))?; // NOTE: since `get_serial_port_info` filters out all PCI Port and Bluetooth @@ -319,7 +321,7 @@ pub fn connect( }; Ok(Flasher::connect( - interface, + Box::new(serial_port), port_info, args.baud.or(config.baudrate), !args.no_stub, @@ -432,7 +434,7 @@ pub fn serial_monitor(args: MonitorArgs, config: &Config) -> Result<()> { }; monitor( - flasher.into_interface(), + flasher.into_serial(), elf.as_deref(), pid, args.connect_args.baud.unwrap_or(default_baud), diff --git a/espflash/src/cli/monitor/mod.rs b/espflash/src/cli/monitor/mod.rs index 250f8c70..6ae3da0d 100644 --- a/espflash/src/cli/monitor/mod.rs +++ b/espflash/src/cli/monitor/mod.rs @@ -21,12 +21,13 @@ use crossterm::{ }; use log::error; use miette::{IntoDiagnostic, Result}; +#[cfg(feature = "serialport")] +use serialport::SerialPort; use strum::{Display, EnumIter, EnumString, VariantNames}; use crate::{ cli::monitor::parser::{InputParser, ResolvingPrinter}, connection::reset_after_flash, - interface::Interface, }; pub mod parser; @@ -65,7 +66,7 @@ impl Drop for RawModeGuard { /// Open a serial monitor on the given interface, using the given input parser. pub fn monitor( - mut serial: Interface, + mut serial: Box, elf: Option<&[u8]>, pid: u16, baud: u32, @@ -78,12 +79,8 @@ pub fn monitor( // Explicitly set the baud rate when starting the serial monitor, to allow using // different rates for flashing. + serial.set_baud_rate(baud).into_diagnostic()?; serial - .serial_port_mut() - .set_baud_rate(baud) - .into_diagnostic()?; - serial - .serial_port_mut() .set_timeout(Duration::from_millis(5)) .into_diagnostic()?; @@ -100,7 +97,7 @@ pub fn monitor( let mut buff = [0; 1024]; loop { - let read_count = match serial.serial_port_mut().read(&mut buff) { + let read_count = match serial.read(&mut buff) { Ok(count) => Ok(count), Err(e) if e.kind() == ErrorKind::TimedOut => Ok(0), Err(e) if e.kind() == ErrorKind::Interrupted => continue, @@ -118,7 +115,7 @@ pub fn monitor( match key.code { KeyCode::Char('c') => break, KeyCode::Char('r') => { - reset_after_flash(&mut serial, pid).into_diagnostic()?; + reset_after_flash(&mut *serial, pid).into_diagnostic()?; continue; } _ => {} @@ -126,11 +123,8 @@ pub fn monitor( } if let Some(bytes) = handle_key_event(key) { - serial - .serial_port_mut() - .write_all(&bytes) - .into_diagnostic()?; - serial.serial_port_mut().flush().into_diagnostic()?; + serial.write_all(&bytes).into_diagnostic()?; + serial.flush().into_diagnostic()?; } } } diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index e9e4db65..d7b79065 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -13,7 +13,7 @@ use std::{ use log::{debug, info}; use regex::Regex; -use serialport::UsbPortInfo; +use serialport::{SerialPort, UsbPortInfo}; use slip_codec::SlipDecoder; #[cfg(unix)] @@ -29,7 +29,6 @@ use crate::{ command::{Command, CommandType}, connection::reset::soft_reset, error::{ConnectionError, Error, ResultExt, RomError, RomErrorKind}, - interface::Interface, }; pub mod reset; @@ -38,6 +37,11 @@ const MAX_CONNECT_ATTEMPTS: usize = 7; const MAX_SYNC_ATTEMPTS: usize = 5; pub(crate) const USB_SERIAL_JTAG_PID: u16 = 0x1001; +#[cfg(unix)] +pub type Port = serialport::TTYPort; +#[cfg(windows)] +pub type Port = serialport::COMPort; + #[derive(Debug, Clone)] pub enum CommandResponseValue { ValueU32(u32), @@ -94,7 +98,7 @@ pub struct CommandResponse { /// An established connection with a target device pub struct Connection { - serial: Interface, + serial: Box, port_info: UsbPortInfo, decoder: SlipDecoder, after_operation: ResetAfterOperation, @@ -103,7 +107,7 @@ pub struct Connection { impl Connection { pub fn new( - serial: Interface, + serial: Box, port_info: UsbPortInfo, after_operation: ResetAfterOperation, before_operation: ResetBeforeOperation, @@ -119,7 +123,7 @@ impl Connection { /// Initialize a connection with a device pub fn begin(&mut self) -> Result<(), Error> { - let port_name = self.serial.serial_port().name().unwrap_or_default(); + let port_name = self.serial.name().unwrap_or_default(); let reset_sequence = construct_reset_strategy_sequence( &port_name, self.port_info.pid, @@ -159,11 +163,11 @@ impl Connection { let mut buff: Vec; if self.before_operation != ResetBeforeOperation::NoReset { // Reset the chip to bootloader (download mode) - reset_strategy.reset(&mut self.serial)?; + reset_strategy.reset(&mut *self.serial)?; - let available_bytes = self.serial.serial_port_mut().bytes_to_read()?; + let available_bytes = self.serial.bytes_to_read()?; buff = vec![0; available_bytes as usize]; - let read_bytes = self.serial.serial_port_mut().read(&mut buff)? as u32; + let read_bytes = self.serial.read(&mut buff)? as u32; if read_bytes != available_bytes { return Err(Error::Connection(ConnectionError::ReadMissmatch( @@ -253,7 +257,7 @@ impl Connection { // Reset the device pub fn reset(&mut self) -> Result<(), Error> { - reset_after_flash(&mut self.serial, self.port_info.pid)?; + reset_after_flash(&mut *self.serial, self.port_info.pid)?; Ok(()) } @@ -261,7 +265,7 @@ impl Connection { // Reset the device taking into account the reset after argument pub fn reset_after(&mut self, is_stub: bool) -> Result<(), Error> { match self.after_operation { - ResetAfterOperation::HardReset => HardReset.reset(&mut self.serial), + ResetAfterOperation::HardReset => HardReset.reset(&mut *self.serial), ResetAfterOperation::NoReset => { info!("Staying in bootloader"); soft_reset(self, true, is_stub)?; @@ -278,36 +282,36 @@ impl Connection { // Reset the device to flash mode pub fn reset_to_flash(&mut self, extra_delay: bool) -> Result<(), Error> { if self.port_info.pid == USB_SERIAL_JTAG_PID { - UsbJtagSerialReset.reset(&mut self.serial) + UsbJtagSerialReset.reset(&mut *self.serial) } else { #[cfg(unix)] if UnixTightReset::new(extra_delay) - .reset(&mut self.serial) + .reset(&mut *self.serial) .is_ok() { return Ok(()); } - ClassicReset::new(extra_delay).reset(&mut self.serial) + ClassicReset::new(extra_delay).reset(&mut *self.serial) } } /// Set timeout for the serial port pub fn set_timeout(&mut self, timeout: Duration) -> Result<(), Error> { - self.serial.serial_port_mut().set_timeout(timeout)?; + self.serial.set_timeout(timeout)?; Ok(()) } /// Set baud rate for the serial port pub fn set_baud(&mut self, speed: u32) -> Result<(), Error> { - self.serial.serial_port_mut().set_baud_rate(speed)?; + self.serial.set_baud_rate(speed)?; Ok(()) } /// Get the current baud rate of the serial port pub fn get_baud(&self) -> Result { - Ok(self.serial.serial_port().baud_rate()?) + Ok(self.serial.baud_rate()?) } /// Run a command with a timeout defined by the command type @@ -316,7 +320,7 @@ impl Connection { F: FnMut(&mut Connection) -> Result, { let old_timeout = { - let serial = self.serial.serial_port_mut(); + let serial = self.serial.as_mut(); let old_timeout = serial.timeout(); serial.set_timeout(timeout)?; old_timeout @@ -324,7 +328,7 @@ impl Connection { let result = f(self); - self.serial.serial_port_mut().set_timeout(old_timeout)?; + self.serial.set_timeout(old_timeout)?; result } @@ -389,8 +393,7 @@ impl Connection { /// Write raw data to the serial port pub fn write_raw(&mut self, data: u32) -> Result<(), Error> { - let serial = self.serial.serial_port_mut(); - + let serial = self.serial.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; let mut writer = BufWriter::new(serial); let mut encoder = SlipEncoder::new(&mut writer)?; @@ -403,7 +406,7 @@ impl Connection { /// Write a command to the serial port pub fn write_command(&mut self, command: Command) -> Result<(), Error> { debug!("Writing command: {:?}", command); - let serial = self.serial.serial_port_mut(); + let serial = self.serial.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; let mut writer = BufWriter::new(serial); @@ -473,12 +476,12 @@ impl Connection { /// Flush the serial port pub fn flush(&mut self) -> Result<(), Error> { - self.serial.serial_port_mut().flush()?; + self.serial.flush()?; Ok(()) } /// Turn a serial port into a Interface - pub fn into_interface(self) -> Interface { + pub fn into_serial(self) -> Box { self.serial } @@ -489,7 +492,7 @@ impl Connection { } /// Reset the target device when flashing has completed -pub fn reset_after_flash(serial: &mut Interface, pid: u16) -> Result<(), serialport::Error> { +pub fn reset_after_flash(serial: &mut dyn SerialPort, pid: u16) -> Result<(), serialport::Error> { sleep(Duration::from_millis(100)); if pid == USB_SERIAL_JTAG_PID { diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index fbd2d0dd..7025f0bd 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -1,18 +1,25 @@ //! This entire module is copied from `esptool.py` (https://github.com/espressif/esptool/blob/a8586d02b1305ebc687d31783437a7f4d4dbb70f/esptool/reset.py) #[cfg(unix)] -use std::{io, os::fd::AsRawFd}; +use std::{ + any::Any, + io, + os::fd::{AsRawFd, RawFd}, +}; use std::{thread::sleep, time::Duration}; use log::debug; +use serialport::{SerialPort, TTYPort}; use strum::{Display, EnumIter, EnumString, VariantNames}; +#[cfg(unix)] +use libc::ioctl; + use crate::{ command::{Command, CommandType}, connection::{Connection, USB_SERIAL_JTAG_PID}, error::Error, flasher, - interface::Interface, }; /// Default time to wait before releasing the boot pin after a reset @@ -20,23 +27,18 @@ const DEFAULT_RESET_DELAY: u64 = 50; // ms /// Amount of time to wait if the default reset delay does not work const EXTRA_RESET_DELAY: u64 = 500; // ms -#[cfg(unix)] -use libc::ioctl; - /// Some strategy for resting a target device pub trait ResetStrategy { - fn reset(&self, interface: &mut Interface) -> Result<(), Error>; + fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error>; - fn set_dtr(&self, interface: &mut Interface, level: bool) -> Result<(), Error> { - interface - .serial_port_mut() - .write_data_terminal_ready(level)?; + fn set_dtr(&self, serial_port: &mut dyn SerialPort, level: bool) -> Result<(), Error> { + serial_port.write_data_terminal_ready(level)?; Ok(()) } - fn set_rts(&self, interface: &mut Interface, level: bool) -> Result<(), Error> { - interface.serial_port_mut().write_request_to_send(level)?; + fn set_rts(&self, serial_port: &mut dyn SerialPort, level: bool) -> Result<(), Error> { + serial_port.write_request_to_send(level)?; Ok(()) } @@ -44,11 +46,11 @@ pub trait ResetStrategy { #[cfg(unix)] fn set_dtr_rts( &self, - interface: &mut Interface, + serial_port: &mut dyn SerialPort, dtr_level: bool, rts_level: bool, ) -> Result<(), Error> { - let fd = interface.as_raw_fd(); + let fd = serial_port.as_raw_fd(); let mut status: i32 = 0; match unsafe { ioctl(fd, libc::TIOCMGET, &status) } { 0 => (), @@ -94,29 +96,29 @@ impl ClassicReset { } impl ResetStrategy for ClassicReset { - fn reset(&self, interface: &mut Interface) -> Result<(), Error> { + fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { debug!( "Using Classic reset strategy with delay of {}ms", self.delay ); - self.set_rts(interface, false)?; - self.set_dtr(interface, false)?; + self.set_rts(serial_port, false)?; + self.set_dtr(serial_port, false)?; - self.set_rts(interface, true)?; - self.set_dtr(interface, true)?; + self.set_rts(serial_port, true)?; + self.set_dtr(serial_port, true)?; - self.set_rts(interface, true)?; // EN = LOW, chip in reset - self.set_dtr(interface, false)?; // IO0 = HIGH + self.set_rts(serial_port, true)?; // EN = LOW, chip in reset + self.set_dtr(serial_port, false)?; // IO0 = HIGH sleep(Duration::from_millis(100)); - self.set_rts(interface, false)?; // EN = HIGH, chip out of reset - self.set_dtr(interface, true)?; // IO0 = LOW + self.set_rts(serial_port, false)?; // EN = HIGH, chip out of reset + self.set_dtr(serial_port, true)?; // IO0 = LOW sleep(Duration::from_millis(self.delay)); - self.set_rts(interface, false)?; - self.set_dtr(interface, false)?; // IO0 = HIGH, done + self.set_rts(serial_port, false)?; + self.set_dtr(serial_port, false)?; // IO0 = HIGH, done Ok(()) } @@ -143,26 +145,48 @@ impl UnixTightReset { } } +// // Extension trait to provide as_mut_any method for trait objects +// trait AsMutAny { +// fn as_mut_any(&mut self) -> &mut dyn Any; +// } + +// impl AsMutAny for dyn SerialPort { +// fn as_mut_any(&mut self) -> &mut dyn Any { +// self +// } +// } + +#[cfg(unix)] +impl AsRawFd for SerialPort { + fn as_raw_fd(&self) -> RawFd { + self.serial_port.as_raw_fd() + } +} + #[cfg(unix)] impl ResetStrategy for UnixTightReset { - fn reset(&self, interface: &mut Interface) -> Result<(), Error> { + fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { debug!( "Using UnixTight reset strategy with delay of {}ms", self.delay ); + // let tty_port = serial_port as &mut TTYPort; + // let tty_port = serial_port.as_mut_any().downcast_mut::().unwrap(); + // let tty_port = serial_port.as_any().downcast_mut::().unwrap(); + // .downcast_mut::().unwrap(); - self.set_dtr_rts(interface, false, false)?; - self.set_dtr_rts(interface, true, true)?; - self.set_dtr_rts(interface, false, true)?; // IO = HIGH, EN = LOW, chip in reset + // self.set_dtr_rts(serial_port, false, false)?; + // self.set_dtr_rts(serial_port, true, true)?; + // self.set_dtr_rts(serial_port, false, true)?; // IO = HIGH, EN = LOW, chip in reset sleep(Duration::from_millis(100)); - self.set_dtr_rts(interface, true, false)?; // IO0 = LOW, EN = HIGH, chip out of reset + // self.set_dtr_rts(serial_port, true, false)?; // IO0 = LOW, EN = HIGH, chip out of reset sleep(Duration::from_millis(self.delay)); - self.set_dtr_rts(interface, false, false)?; // IO0 = HIGH, done - self.set_dtr(interface, false)?; // Needed in some environments to ensure IO0 = HIGH + self.set_dtr_rts(serial_port, false, false)?; // IO0 = HIGH, done + self.set_dtr(serial_port, false)?; // Needed in some environments to ensure IO0 = HIGH Ok(()) } @@ -174,27 +198,27 @@ impl ResetStrategy for UnixTightReset { pub struct UsbJtagSerialReset; impl ResetStrategy for UsbJtagSerialReset { - fn reset(&self, interface: &mut Interface) -> Result<(), Error> { + fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { debug!("Using UsbJtagSerial reset strategy"); - self.set_rts(interface, false)?; - self.set_dtr(interface, false)?; // Idle + self.set_rts(serial_port, false)?; + self.set_dtr(serial_port, false)?; // Idle sleep(Duration::from_millis(100)); - self.set_rts(interface, false)?; - self.set_dtr(interface, true)?; // Set IO0 + self.set_rts(serial_port, false)?; + self.set_dtr(serial_port, true)?; // Set IO0 sleep(Duration::from_millis(100)); - self.set_rts(interface, true)?; // Reset. Calls inverted to go through (1,1) instead of (0,0) - self.set_dtr(interface, false)?; - self.set_rts(interface, true)?; // RTS set as Windows only propagates DTR on RTS setting + self.set_rts(serial_port, true)?; // Reset. Calls inverted to go through (1,1) instead of (0,0) + self.set_dtr(serial_port, false)?; + self.set_rts(serial_port, true)?; // RTS set as Windows only propagates DTR on RTS setting sleep(Duration::from_millis(100)); - self.set_rts(interface, false)?; - self.set_dtr(interface, false)?; + self.set_rts(serial_port, false)?; + self.set_dtr(serial_port, false)?; Ok(()) } @@ -207,12 +231,12 @@ impl ResetStrategy for UsbJtagSerialReset { pub struct HardReset; impl ResetStrategy for HardReset { - fn reset(&self, interface: &mut Interface) -> Result<(), Error> { + fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { debug!("Using HardReset reset strategy"); - self.set_rts(interface, true)?; + self.set_rts(serial_port, true)?; sleep(Duration::from_millis(100)); - self.set_rts(interface, false)?; + self.set_rts(serial_port, false)?; Ok(()) } diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index dd8fe507..d94ebc0f 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -20,25 +20,22 @@ use md5::{Digest, Md5}; use miette::{Context, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; #[cfg(feature = "serialport")] -use serialport::UsbPortInfo; +use serialport::{SerialPort, UsbPortInfo}; use strum::IntoEnumIterator; use strum::{Display, EnumIter, VariantNames}; use self::stubs::FlashStub; +#[cfg(feature = "serialport")] +use crate::connection::{ + reset::{ResetAfterOperation, ResetBeforeOperation}, + Connection, +}; use crate::{ command::{Command, CommandType}, elf::{ElfFirmwareImage, FirmwareImage, RomSegment}, error::{ConnectionError, Error, ResultExt}, targets::{Chip, XtalFrequency}, }; -#[cfg(feature = "serialport")] -use crate::{ - connection::{ - reset::{ResetAfterOperation, ResetBeforeOperation}, - Connection, - }, - interface::Interface, -}; mod stubs; @@ -572,7 +569,7 @@ pub struct Flasher { #[cfg(feature = "serialport")] impl Flasher { pub fn connect( - serial: Interface, + serial: Box, port_info: UsbPortInfo, speed: Option, use_stub: bool, @@ -1071,6 +1068,10 @@ impl Flasher { Ok(()) } + pub fn into_serial(self) -> Box { + self.connection.into_serial() + } + pub fn get_usb_pid(&self) -> Result { self.connection.get_usb_pid() } @@ -1191,9 +1192,9 @@ impl Flasher { Ok(()) } - pub fn into_interface(self) -> Interface { - self.connection.into_interface() - } + // pub fn into_interface(self) -> Interface { + // self.connection.into_interface() + // } } pub(crate) fn checksum(data: &[u8], mut checksum: u8) -> u8 { From bd41e51874446c5890009fa94142fa56c0ffc548 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 16 Feb 2024 10:50:37 +0100 Subject: [PATCH 3/6] feat: Replace Interface types --- cargo-espflash/src/main.rs | 2 +- espflash/src/cli/mod.rs | 2 +- espflash/src/cli/monitor/mod.rs | 8 +++---- espflash/src/connection/mod.rs | 29 +++++++++++++----------- espflash/src/connection/reset.rs | 38 ++++++++++++++------------------ espflash/src/flasher/mod.rs | 8 +++---- 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/cargo-espflash/src/main.rs b/cargo-espflash/src/main.rs index 3f7ebbe0..6759c626 100644 --- a/cargo-espflash/src/main.rs +++ b/cargo-espflash/src/main.rs @@ -354,7 +354,7 @@ fn flash(args: FlashArgs, config: &Config) -> Result<()> { }; monitor( - flasher.into_interface(), + flasher.into_serial(), Some(&elf_data), pid, args.flash_args.monitor_baud.unwrap_or(default_baud), diff --git a/espflash/src/cli/mod.rs b/espflash/src/cli/mod.rs index 2aabdc13..4dc7f783 100644 --- a/espflash/src/cli/mod.rs +++ b/espflash/src/cli/mod.rs @@ -321,7 +321,7 @@ pub fn connect( }; Ok(Flasher::connect( - Box::new(serial_port), + *Box::new(serial_port), port_info, args.baud.or(config.baudrate), !args.no_stub, diff --git a/espflash/src/cli/monitor/mod.rs b/espflash/src/cli/monitor/mod.rs index 6ae3da0d..0871158f 100644 --- a/espflash/src/cli/monitor/mod.rs +++ b/espflash/src/cli/monitor/mod.rs @@ -11,7 +11,7 @@ //! in our monitor the output is displayed immediately upon reading. use std::{ - io::{stdout, ErrorKind, Write}, + io::{stdout, ErrorKind, Read, Write}, time::Duration, }; @@ -27,7 +27,7 @@ use strum::{Display, EnumIter, EnumString, VariantNames}; use crate::{ cli::monitor::parser::{InputParser, ResolvingPrinter}, - connection::reset_after_flash, + connection::{reset_after_flash, Port}, }; pub mod parser; @@ -66,7 +66,7 @@ impl Drop for RawModeGuard { /// Open a serial monitor on the given interface, using the given input parser. pub fn monitor( - mut serial: Box, + mut serial: Port, elf: Option<&[u8]>, pid: u16, baud: u32, @@ -115,7 +115,7 @@ pub fn monitor( match key.code { KeyCode::Char('c') => break, KeyCode::Char('r') => { - reset_after_flash(&mut *serial, pid).into_diagnostic()?; + reset_after_flash(&mut serial, pid).into_diagnostic()?; continue; } _ => {} diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index d7b79065..c5e04435 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -5,7 +5,7 @@ //! device. use std::{ - io::{BufWriter, Write}, + io::{BufWriter, Read, Write}, iter::zip, thread::sleep, time::Duration, @@ -98,7 +98,7 @@ pub struct CommandResponse { /// An established connection with a target device pub struct Connection { - serial: Box, + serial: Port, port_info: UsbPortInfo, decoder: SlipDecoder, after_operation: ResetAfterOperation, @@ -107,7 +107,7 @@ pub struct Connection { impl Connection { pub fn new( - serial: Box, + serial: Port, port_info: UsbPortInfo, after_operation: ResetAfterOperation, before_operation: ResetBeforeOperation, @@ -163,7 +163,7 @@ impl Connection { let mut buff: Vec; if self.before_operation != ResetBeforeOperation::NoReset { // Reset the chip to bootloader (download mode) - reset_strategy.reset(&mut *self.serial)?; + reset_strategy.reset(&mut self.serial)?; let available_bytes = self.serial.bytes_to_read()?; buff = vec![0; available_bytes as usize]; @@ -257,7 +257,7 @@ impl Connection { // Reset the device pub fn reset(&mut self) -> Result<(), Error> { - reset_after_flash(&mut *self.serial, self.port_info.pid)?; + reset_after_flash(&mut self.serial, self.port_info.pid)?; Ok(()) } @@ -265,7 +265,7 @@ impl Connection { // Reset the device taking into account the reset after argument pub fn reset_after(&mut self, is_stub: bool) -> Result<(), Error> { match self.after_operation { - ResetAfterOperation::HardReset => HardReset.reset(&mut *self.serial), + ResetAfterOperation::HardReset => HardReset.reset(&mut self.serial), ResetAfterOperation::NoReset => { info!("Staying in bootloader"); soft_reset(self, true, is_stub)?; @@ -282,17 +282,17 @@ impl Connection { // Reset the device to flash mode pub fn reset_to_flash(&mut self, extra_delay: bool) -> Result<(), Error> { if self.port_info.pid == USB_SERIAL_JTAG_PID { - UsbJtagSerialReset.reset(&mut *self.serial) + UsbJtagSerialReset.reset(&mut self.serial) } else { #[cfg(unix)] if UnixTightReset::new(extra_delay) - .reset(&mut *self.serial) + .reset(&mut self.serial) .is_ok() { return Ok(()); } - ClassicReset::new(extra_delay).reset(&mut *self.serial) + ClassicReset::new(extra_delay).reset(&mut self.serial) } } @@ -320,7 +320,8 @@ impl Connection { F: FnMut(&mut Connection) -> Result, { let old_timeout = { - let serial = self.serial.as_mut(); + let mut binding = Box::new(&mut self.serial); + let serial = binding.as_mut(); let old_timeout = serial.timeout(); serial.set_timeout(timeout)?; old_timeout @@ -393,7 +394,8 @@ impl Connection { /// Write raw data to the serial port pub fn write_raw(&mut self, data: u32) -> Result<(), Error> { - let serial = self.serial.as_mut(); + let mut binding = Box::new(&mut self.serial); + let serial = binding.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; let mut writer = BufWriter::new(serial); let mut encoder = SlipEncoder::new(&mut writer)?; @@ -406,7 +408,8 @@ impl Connection { /// Write a command to the serial port pub fn write_command(&mut self, command: Command) -> Result<(), Error> { debug!("Writing command: {:?}", command); - let serial = self.serial.as_mut(); + let mut binding = Box::new(&mut self.serial); + let serial = binding.as_mut(); serial.clear(serialport::ClearBuffer::Input)?; let mut writer = BufWriter::new(serial); @@ -481,7 +484,7 @@ impl Connection { } /// Turn a serial port into a Interface - pub fn into_serial(self) -> Box { + pub fn into_serial(self) -> Port { self.serial } diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index 7025f0bd..8b82a28f 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -1,15 +1,11 @@ //! This entire module is copied from `esptool.py` (https://github.com/espressif/esptool/blob/a8586d02b1305ebc687d31783437a7f4d4dbb70f/esptool/reset.py) #[cfg(unix)] -use std::{ - any::Any, - io, - os::fd::{AsRawFd, RawFd}, -}; +use std::{io, os::fd::AsRawFd}; use std::{thread::sleep, time::Duration}; use log::debug; -use serialport::{SerialPort, TTYPort}; +use serialport::SerialPort; use strum::{Display, EnumIter, EnumString, VariantNames}; #[cfg(unix)] @@ -17,7 +13,7 @@ use libc::ioctl; use crate::{ command::{Command, CommandType}, - connection::{Connection, USB_SERIAL_JTAG_PID}, + connection::{Connection, Port, USB_SERIAL_JTAG_PID}, error::Error, flasher, }; @@ -29,15 +25,15 @@ const EXTRA_RESET_DELAY: u64 = 500; // ms /// Some strategy for resting a target device pub trait ResetStrategy { - fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error>; + fn reset(&self, serial_port: &mut Port) -> Result<(), Error>; - fn set_dtr(&self, serial_port: &mut dyn SerialPort, level: bool) -> Result<(), Error> { + fn set_dtr(&self, serial_port: &mut Port, level: bool) -> Result<(), Error> { serial_port.write_data_terminal_ready(level)?; Ok(()) } - fn set_rts(&self, serial_port: &mut dyn SerialPort, level: bool) -> Result<(), Error> { + fn set_rts(&self, serial_port: &mut Port, level: bool) -> Result<(), Error> { serial_port.write_request_to_send(level)?; Ok(()) @@ -46,7 +42,7 @@ pub trait ResetStrategy { #[cfg(unix)] fn set_dtr_rts( &self, - serial_port: &mut dyn SerialPort, + serial_port: &mut Port, dtr_level: bool, rts_level: bool, ) -> Result<(), Error> { @@ -96,7 +92,7 @@ impl ClassicReset { } impl ResetStrategy for ClassicReset { - fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { + fn reset(&self, serial_port: &mut Port) -> Result<(), Error> { debug!( "Using Classic reset strategy with delay of {}ms", self.delay @@ -156,16 +152,16 @@ impl UnixTightReset { // } // } -#[cfg(unix)] -impl AsRawFd for SerialPort { - fn as_raw_fd(&self) -> RawFd { - self.serial_port.as_raw_fd() - } -} +// #[cfg(unix)] +// impl AsRawFd for SerialPort { +// fn as_raw_fd(&self) -> RawFd { +// self.serial_port.as_raw_fd() +// } +// } #[cfg(unix)] impl ResetStrategy for UnixTightReset { - fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { + fn reset(&self, serial_port: &mut Port) -> Result<(), Error> { debug!( "Using UnixTight reset strategy with delay of {}ms", self.delay @@ -198,7 +194,7 @@ impl ResetStrategy for UnixTightReset { pub struct UsbJtagSerialReset; impl ResetStrategy for UsbJtagSerialReset { - fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { + fn reset(&self, serial_port: &mut Port) -> Result<(), Error> { debug!("Using UsbJtagSerial reset strategy"); self.set_rts(serial_port, false)?; @@ -231,7 +227,7 @@ impl ResetStrategy for UsbJtagSerialReset { pub struct HardReset; impl ResetStrategy for HardReset { - fn reset(&self, serial_port: &mut dyn SerialPort) -> Result<(), Error> { + fn reset(&self, serial_port: &mut Port) -> Result<(), Error> { debug!("Using HardReset reset strategy"); self.set_rts(serial_port, true)?; diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index d94ebc0f..556a5688 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -20,7 +20,7 @@ use md5::{Digest, Md5}; use miette::{Context, IntoDiagnostic, Result}; use serde::{Deserialize, Serialize}; #[cfg(feature = "serialport")] -use serialport::{SerialPort, UsbPortInfo}; +use serialport::UsbPortInfo; use strum::IntoEnumIterator; use strum::{Display, EnumIter, VariantNames}; @@ -28,7 +28,7 @@ use self::stubs::FlashStub; #[cfg(feature = "serialport")] use crate::connection::{ reset::{ResetAfterOperation, ResetBeforeOperation}, - Connection, + Connection, Port, }; use crate::{ command::{Command, CommandType}, @@ -569,7 +569,7 @@ pub struct Flasher { #[cfg(feature = "serialport")] impl Flasher { pub fn connect( - serial: Box, + serial: Port, port_info: UsbPortInfo, speed: Option, use_stub: bool, @@ -1068,7 +1068,7 @@ impl Flasher { Ok(()) } - pub fn into_serial(self) -> Box { + pub fn into_serial(self) -> Port { self.connection.into_serial() } From 297c88ec5b103dafa61458e7d74c078fa40f9781 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 16 Feb 2024 10:54:07 +0100 Subject: [PATCH 4/6] feat: Remove interface mod --- espflash/src/cli/monitor/mod.rs | 2 +- espflash/src/connection/mod.rs | 2 +- espflash/src/flasher/mod.rs | 4 -- espflash/src/interface.rs | 79 --------------------------------- espflash/src/lib.rs | 3 -- 5 files changed, 2 insertions(+), 88 deletions(-) delete mode 100644 espflash/src/interface.rs diff --git a/espflash/src/cli/monitor/mod.rs b/espflash/src/cli/monitor/mod.rs index 0871158f..41a80cbf 100644 --- a/espflash/src/cli/monitor/mod.rs +++ b/espflash/src/cli/monitor/mod.rs @@ -64,7 +64,7 @@ impl Drop for RawModeGuard { } } -/// Open a serial monitor on the given interface, using the given input parser. +/// Open a serial monitor on the given serial port, using the given input parser. pub fn monitor( mut serial: Port, elf: Option<&[u8]>, diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index c5e04435..b1773309 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -483,7 +483,7 @@ impl Connection { Ok(()) } - /// Turn a serial port into a Interface + /// Turn a serial port into a [Port] pub fn into_serial(self) -> Port { self.serial } diff --git a/espflash/src/flasher/mod.rs b/espflash/src/flasher/mod.rs index 556a5688..b882e03d 100644 --- a/espflash/src/flasher/mod.rs +++ b/espflash/src/flasher/mod.rs @@ -1191,10 +1191,6 @@ impl Flasher { Ok(()) } - - // pub fn into_interface(self) -> Interface { - // self.connection.into_interface() - // } } pub(crate) fn checksum(data: &[u8], mut checksum: u8) -> u8 { diff --git a/espflash/src/interface.rs b/espflash/src/interface.rs deleted file mode 100644 index 77b0e552..00000000 --- a/espflash/src/interface.rs +++ /dev/null @@ -1,79 +0,0 @@ -//! Serial port wrapper to support platform-specific functionality - -use std::io::Read; -#[cfg(unix)] -use std::os::fd::{AsRawFd, RawFd}; - -use miette::{Context, Result}; -use serialport::{FlowControl, SerialPort, SerialPortInfo}; - -use crate::error::Error; - -#[cfg(unix)] -type Port = serialport::TTYPort; -#[cfg(windows)] -type Port = serialport::COMPort; - -/// Wrapper around SerialPort where platform-specific modifications can be -/// implemented. -pub struct Interface { - /// Hardware serial port used for communication - pub serial_port: Port, -} - -/// Open a serial port -fn open_port(port_info: &SerialPortInfo) -> Result { - serialport::new(&port_info.port_name, 115_200) - .flow_control(FlowControl::None) - .open_native() - .map_err(Error::from) - .wrap_err_with(|| format!("Failed to open serial port {}", port_info.port_name)) -} - -impl Interface { - pub fn new(port_info: &SerialPortInfo) -> Result { - Ok(Self { - serial_port: open_port(port_info)?, - }) - } - - /// Set the level of the DTR pin - pub fn write_data_terminal_ready(&mut self, pin_state: bool) -> serialport::Result<()> { - self.serial_port.write_data_terminal_ready(pin_state) - } - - /// Set the level of the RTS pin - pub fn write_request_to_send(&mut self, pin_state: bool) -> serialport::Result<()> { - self.serial_port.write_request_to_send(pin_state) - } - - /// Turn an [Interface] into a [SerialPort] - pub fn into_serial(self) -> Box { - Box::new(self.serial_port) - } - - /// Turn an [Interface] into a `&`[SerialPort] - pub fn serial_port(&self) -> &dyn SerialPort { - &self.serial_port - } - - /// Turn an [Interface] into a `&mut `[SerialPort] - pub fn serial_port_mut(&mut self) -> &mut dyn SerialPort { - &mut self.serial_port - } -} - -// Note(dbuga): this `impl` is necessary because using `dyn SerialPort` as `dyn -// Read` requires trait_upcasting which isn't stable yet. -impl Read for Interface { - fn read(&mut self, buf: &mut [u8]) -> std::io::Result { - self.serial_port.read(buf) - } -} - -#[cfg(unix)] -impl AsRawFd for Interface { - fn as_raw_fd(&self) -> RawFd { - self.serial_port.as_raw_fd() - } -} diff --git a/espflash/src/lib.rs b/espflash/src/lib.rs index 9306ea33..07bf0e84 100644 --- a/espflash/src/lib.rs +++ b/espflash/src/lib.rs @@ -39,9 +39,6 @@ pub mod elf; pub mod error; pub mod flasher; pub mod image_format; -#[cfg(feature = "serialport")] -#[cfg_attr(docsrs, doc(cfg(feature = "serialport")))] -pub mod interface; pub mod targets; /// Logging utilities From 7fcf35aa67e9b32a76416481104a02f4f2b28031 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 16 Feb 2024 10:56:21 +0100 Subject: [PATCH 5/6] docs: Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a88e2ed5..7f4b98ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove support for the ESP8266 (#576) - Remove the direct boot image format (#577) +- Remove support for Raspberry Pi's internal UART peripherals (#585) ## [2.1.0] - 2023-10-03 From dfc22596f7863b5a831003801eb8701597fda0d5 Mon Sep 17 00:00:00 2001 From: Sergio Gasquez Date: Fri, 16 Feb 2024 11:01:46 +0100 Subject: [PATCH 6/6] chore: Remove unused comments --- espflash/src/connection/mod.rs | 2 +- espflash/src/connection/reset.rs | 30 ++++-------------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/espflash/src/connection/mod.rs b/espflash/src/connection/mod.rs index b1773309..8354cac0 100644 --- a/espflash/src/connection/mod.rs +++ b/espflash/src/connection/mod.rs @@ -495,7 +495,7 @@ impl Connection { } /// Reset the target device when flashing has completed -pub fn reset_after_flash(serial: &mut dyn SerialPort, pid: u16) -> Result<(), serialport::Error> { +pub fn reset_after_flash(serial: &mut Port, pid: u16) -> Result<(), serialport::Error> { sleep(Duration::from_millis(100)); if pid == USB_SERIAL_JTAG_PID { diff --git a/espflash/src/connection/reset.rs b/espflash/src/connection/reset.rs index 8b82a28f..77330b02 100644 --- a/espflash/src/connection/reset.rs +++ b/espflash/src/connection/reset.rs @@ -141,24 +141,6 @@ impl UnixTightReset { } } -// // Extension trait to provide as_mut_any method for trait objects -// trait AsMutAny { -// fn as_mut_any(&mut self) -> &mut dyn Any; -// } - -// impl AsMutAny for dyn SerialPort { -// fn as_mut_any(&mut self) -> &mut dyn Any { -// self -// } -// } - -// #[cfg(unix)] -// impl AsRawFd for SerialPort { -// fn as_raw_fd(&self) -> RawFd { -// self.serial_port.as_raw_fd() -// } -// } - #[cfg(unix)] impl ResetStrategy for UnixTightReset { fn reset(&self, serial_port: &mut Port) -> Result<(), Error> { @@ -166,18 +148,14 @@ impl ResetStrategy for UnixTightReset { "Using UnixTight reset strategy with delay of {}ms", self.delay ); - // let tty_port = serial_port as &mut TTYPort; - // let tty_port = serial_port.as_mut_any().downcast_mut::().unwrap(); - // let tty_port = serial_port.as_any().downcast_mut::().unwrap(); - // .downcast_mut::().unwrap(); - // self.set_dtr_rts(serial_port, false, false)?; - // self.set_dtr_rts(serial_port, true, true)?; - // self.set_dtr_rts(serial_port, false, true)?; // IO = HIGH, EN = LOW, chip in reset + self.set_dtr_rts(serial_port, false, false)?; + self.set_dtr_rts(serial_port, true, true)?; + self.set_dtr_rts(serial_port, false, true)?; // IO = HIGH, EN = LOW, chip in reset sleep(Duration::from_millis(100)); - // self.set_dtr_rts(serial_port, true, false)?; // IO0 = LOW, EN = HIGH, chip out of reset + self.set_dtr_rts(serial_port, true, false)?; // IO0 = LOW, EN = HIGH, chip out of reset sleep(Duration::from_millis(self.delay));