Try a hardreset to init on the stlink if attach doesn't work
@@ -137,6 +137,17 @@ impl DebugProbe for STLink<STLinkUSBDevice> {
&mut buf,
TIMEOUT,
)?;
+ let result = Self::check_status(&buf);
+
+ match result {
+ Err(StlinkError::CommandFailed(Status::JtagGetIdcodeError)) => {
+ self.target_reset_assert()?;
+ self.attach()?;
+ self.target_reset_deassert()?;
+ Ok(())
+ }
+ result => result,
+ }?;
log::debug!("Successfully initialized SWD.");
@@ -167,7 +178,6 @@ impl DebugProbe for STLink<STLinkUSBDevice> {
self.enter_idle()
}
- /// Asserts the nRESET pin.
fn target_reset(&mut self) -> Result<(), DebugProbeError> {
let mut buf = [0; 2];
self.send_jtag_command(
@@ -179,7 +189,10 @@ impl DebugProbe for STLink<STLinkUSBDevice> {
&[],
&mut buf,
TIMEOUT,
- )
+ )?;
+
+ Self::check_status(&buf)?;
+ Ok(())
}
fn select_protocol(&mut self, protocol: WireProtocol) -> Result<(), DebugProbeError> {
@@ -473,6 +486,42 @@ impl<D: StLinkUsb> STLink<D> {
self.get_target_voltage().map(|_| ())
}
+ /// Asserts the nRESET pin.
+ fn target_reset_assert(&mut self) -> Result<(), DebugProbeError> {
+ let mut buf = [0; 2];
+ self.device.write(
+ vec![
+ commands::JTAG_COMMAND,
+ commands::JTAG_DRIVE_NRST,
+ commands::JTAG_DRIVE_NRST_LOW,
+ ],
+ &[],
+ &mut buf,
+ TIMEOUT,
+ )?;
+
+ Self::check_status(&buf)?;
+ Ok(())
+ }
+
+ /// Deasserts the nRESET pin.
+ fn target_reset_deassert(&mut self) -> Result<(), DebugProbeError> {
+ let mut buf = [0; 2];
+ self.device.write(
+ vec![
+ commands::JTAG_COMMAND,
+ commands::JTAG_DRIVE_NRST,
+ commands::JTAG_DRIVE_NRST_HIGH,
+ ],
+ &[],
+ &mut buf,
+ TIMEOUT,
+ )?;
+
+ Self::check_status(&buf)?;
+ Ok(())
+ }
+
/// sets the SWD frequency.
pub fn set_swd_frequency(
&mut self,
@@ -488,7 +537,9 @@ impl<D: StLinkUsb> STLink<D> {
&[],
&mut buf,
TIMEOUT,
- )
+ )?;
+ Self::check_status(&buf)?;
+ Ok(())
}
/// Sets the JTAG frequency.
@@ -506,7 +557,9 @@ impl<D: StLinkUsb> STLink<D> {
&[],
&mut buf,
TIMEOUT,
- )
+ )?;
+ Self::check_status(&buf)?;
+ Ok(())
}
/// Sets the communication frequency (V3 only)
@@ -644,6 +697,7 @@ impl<D: StLinkUsb> STLink<D> {
/// Returns Ok(()) otherwise.
/// This can be called on any status returned from the attached target.
fn check_status(status: &[u8]) -> Result<(), StlinkError> {
+ log::trace!("check_status({:?})", status);
let status = Status::from(status[0]);
if status != Status::JtagOk {
log::warn!("check_status failed: {:?}", status);
