From 9bcd5d0eea98ee1c8fc1cd3766632c096bf5fbe0 Mon Sep 17 00:00:00 2001 From: Raphael Nestler Date: Tue, 12 Nov 2019 16:08:25 +0100 Subject: [PATCH 1/2] Allow deriving stlink Status from primitives --- probe-rs/src/probe/stlink/constants.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/probe-rs/src/probe/stlink/constants.rs b/probe-rs/src/probe/stlink/constants.rs index d5b1a598de..9a09a61d02 100644 --- a/probe-rs/src/probe/stlink/constants.rs +++ b/probe-rs/src/probe/stlink/constants.rs @@ -1,3 +1,6 @@ +use enum_primitive_derive::Primitive; +use num_traits::FromPrimitive; + pub mod commands { // Common commands. pub const GET_VERSION: u8 = 0xf1; @@ -60,6 +63,7 @@ pub mod commands { } /// STLink status codes and messages. +#[derive(Primitive)] pub enum Status { JtagOk = 0x80, JtagUnknownError = 0x01, @@ -92,6 +96,12 @@ pub enum Status { JtagUnknownCmd = 0x42, } +impl From for Status { + fn from(status_byte: u8) -> Status { + Status::from_u8(status_byte).unwrap_or(Status::JtagUnknownError) + } +} + /// Map from SWD frequency in Hertz to delay loop count. pub enum SwdFrequencyToDelayCount { Hz4600000 = 0, From 705b1956c1aabc4f5352763bb6530a0ec4d9e68d Mon Sep 17 00:00:00 2001 From: Raphael Nestler Date: Tue, 12 Nov 2019 16:47:11 +0100 Subject: [PATCH 2/2] Bubble up StLink Status errors This improves the reported error to indicate the cause a bit better than just "UnknownError": Error processing command: Custom("Unexpected STLink status 20: SwdDpWait") --- probe-rs/src/probe/debug_probe.rs | 11 ++++++++ probe-rs/src/probe/stlink/constants.rs | 2 +- probe-rs/src/probe/stlink/mod.rs | 37 +++++++++++++++----------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/probe-rs/src/probe/debug_probe.rs b/probe-rs/src/probe/debug_probe.rs index 2b9ff9202d..70ad2a72d3 100644 --- a/probe-rs/src/probe/debug_probe.rs +++ b/probe-rs/src/probe/debug_probe.rs @@ -9,6 +9,7 @@ use log::debug; use crate::memory::adi_v5_memory_interface::ADIMemoryInterface; use crate::memory::MI; use crate::probe::protocol::WireProtocol; +use crate::probe::stlink::constants::Status as StLinkStatus; use std::error::Error; use std::fmt; @@ -33,6 +34,7 @@ pub enum DebugProbeError { TargetPowerUpFailed, Timeout, AccessPortError(AccessPortError), + Custom(String), } impl Error for DebugProbeError { @@ -57,6 +59,15 @@ impl From for DebugProbeError { } } +impl From for DebugProbeError { + fn from(status: StLinkStatus) -> Self { + Self::Custom(format!( + "Unexpected STLink status {}: {:?}", + status as u8, status + )) + } +} + #[derive(Debug, PartialEq)] pub enum Port { DebugPort, diff --git a/probe-rs/src/probe/stlink/constants.rs b/probe-rs/src/probe/stlink/constants.rs index 9a09a61d02..25fa85cf17 100644 --- a/probe-rs/src/probe/stlink/constants.rs +++ b/probe-rs/src/probe/stlink/constants.rs @@ -63,7 +63,7 @@ pub mod commands { } /// STLink status codes and messages. -#[derive(Primitive)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Primitive)] pub enum Status { JtagOk = 0x80, JtagUnknownError = 0x01, diff --git a/probe-rs/src/probe/stlink/mod.rs b/probe-rs/src/probe/stlink/mod.rs index 4ce7e5f88a..21239a8862 100644 --- a/probe-rs/src/probe/stlink/mod.rs +++ b/probe-rs/src/probe/stlink/mod.rs @@ -67,12 +67,12 @@ impl DebugProbe for STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf).and_then(|_| { - // After we checked the status with success, - // We store the current protocol. - self.protocol = protocol; - Ok(protocol) - }) + Self::check_status(&buf)?; + + // After we checked the status with success, + // We store the current protocol. + self.protocol = protocol; + Ok(protocol) } /// Leave debug mode. @@ -93,7 +93,8 @@ impl DebugProbe for STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } } @@ -326,7 +327,8 @@ impl STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } /// Sets the JTAG frequency. @@ -345,7 +347,8 @@ impl STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } pub fn open_ap(&mut self, apsel: impl AccessPort) -> Result<(), DebugProbeError> { @@ -364,7 +367,8 @@ impl STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } } @@ -383,7 +387,8 @@ impl STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } } @@ -402,18 +407,20 @@ impl STLink { &mut buf, TIMEOUT, )?; - Self::check_status(&buf) + Self::check_status(&buf)?; + Ok(()) } /// Validates the status given. /// Returns an `Err(DebugProbeError::UnknownError)` if the status is not `Status::JtagOk`. /// Returns Ok(()) otherwise. /// This can be called on any status returned from the attached target. - fn check_status(status: &[u8]) -> Result<(), DebugProbeError> { + fn check_status(status: &[u8]) -> Result<(), Status> { log::trace!("check_status({:?})", status); - if status[0] != Status::JtagOk as u8 { + let status = Status::from(status[0]); + if status != Status::JtagOk { log::debug!("check_status failed: {:?}", status); - Err(DebugProbeError::UnknownError) + Err(status) } else { Ok(()) }