Skip to content

Commit 9ab462a

Browse files
authored
Merge pull request #54 from esp-rs/deflate-begin-timeout
fix erease timeout not being used for compressed flashing
2 parents 6d3833a + 44c65ff commit 9ab462a

File tree

5 files changed

+64
-25
lines changed

5 files changed

+64
-25
lines changed

espflash/src/connection.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ use std::thread::sleep;
33
use std::time::Duration;
44

55
use crate::encoder::SlipEncoder;
6-
use crate::error::{ConnectionError, Error, RomError};
6+
use crate::error::{ConnectionError, Error, ResultExt, RomError};
7+
use crate::flasher::Command;
78
use binread::io::Cursor;
89
use binread::{BinRead, BinReaderExt};
910
use serial::{BaudRate, SerialPort, SerialPortSettings, SystemPort};
@@ -114,14 +115,15 @@ impl Connection {
114115

115116
pub fn command<Data: LazyBytes<SystemPort>>(
116117
&mut self,
117-
command: u8,
118+
command: Command,
118119
data: Data,
119120
check: u32,
120121
) -> Result<u32, Error> {
121-
self.write_command(command, data, check)?;
122+
self.write_command(command as u8, data, check)
123+
.for_command(command)?;
122124

123125
for _ in 0..100 {
124-
match self.read_response()? {
126+
match self.read_response().for_command(command)? {
125127
Some(response) if response.return_op == command as u8 => {
126128
if response.status == 1 {
127129
let _error = self.flush();

espflash/src/error.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use crate::flasher::Command;
12
use csv::Position;
23
use miette::{Diagnostic, SourceOffset, SourceSpan};
34
use slip_codec::Error as SlipError;
5+
use std::fmt::{Display, Formatter};
46
use std::io;
57
use thiserror::Error;
68

@@ -63,9 +65,9 @@ pub enum ConnectionError {
6365
help("Ensure that the device is connected and your host recognizes the serial adapter")
6466
)]
6567
DeviceNotFound,
66-
#[error("Timeout while running command")]
68+
#[error("Timeout while running {0}command")]
6769
#[diagnostic(code(espflash::timeout))]
68-
Timeout,
70+
Timeout(TimedOutCommand),
6971
#[error("Received packet has invalid SLIP framing")]
7072
#[diagnostic(
7173
code(espflash::slip_framing),
@@ -80,6 +82,26 @@ pub enum ConnectionError {
8082
OverSizedPacket,
8183
}
8284

85+
#[derive(Debug, Default, Clone)]
86+
pub struct TimedOutCommand {
87+
command: Option<Command>,
88+
}
89+
90+
impl From<Command> for TimedOutCommand {
91+
fn from(c: Command) -> Self {
92+
TimedOutCommand { command: Some(c) }
93+
}
94+
}
95+
96+
impl Display for TimedOutCommand {
97+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
98+
match &self.command {
99+
Some(command) => write!(f, "{} ", command),
100+
None => Ok(()),
101+
}
102+
}
103+
}
104+
83105
impl From<serial::Error> for ConnectionError {
84106
fn from(err: serial::Error) -> Self {
85107
match err.kind() {
@@ -110,7 +132,7 @@ impl From<io::Error> for Error {
110132

111133
fn from_error_kind<E: Into<serial::Error>>(kind: io::ErrorKind, err: E) -> ConnectionError {
112134
match kind {
113-
io::ErrorKind::TimedOut => ConnectionError::Timeout,
135+
io::ErrorKind::TimedOut => ConnectionError::Timeout(TimedOutCommand::default()),
114136
io::ErrorKind::NotFound => ConnectionError::DeviceNotFound,
115137
_ => ConnectionError::Serial(err.into()),
116138
}
@@ -197,6 +219,8 @@ impl From<u8> for RomError {
197219
pub(crate) trait ResultExt {
198220
/// mark an error as having occurred during the flashing stage
199221
fn flashing(self) -> Self;
222+
/// mark the command from which this error originates
223+
fn for_command(self, command: Command) -> Self;
200224
}
201225

202226
impl<T> ResultExt for Result<T, Error> {
@@ -206,6 +230,18 @@ impl<T> ResultExt for Result<T, Error> {
206230
res => res,
207231
}
208232
}
233+
234+
fn for_command(self, command: Command) -> Self {
235+
match self {
236+
Err(Error::Connection(ConnectionError::Timeout(_))) => {
237+
Err(Error::Connection(ConnectionError::Timeout(command.into())))
238+
}
239+
Err(Error::Flashing(ConnectionError::Timeout(_))) => {
240+
Err(Error::Flashing(ConnectionError::Timeout(command.into())))
241+
}
242+
res => res,
243+
}
244+
}
209245
}
210246

211247
#[derive(Debug, Error, Diagnostic)]

espflash/src/flash_target/esp32.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ impl FlashTarget for Esp32Target {
2727
fn begin(&mut self, connection: &mut Connection, _image: &FirmwareImage) -> Result<(), Error> {
2828
let spi_params = self.spi_attach_params.encode();
2929
connection.with_timeout(Command::SpiAttach.timeout(), |connection| {
30-
connection.command(Command::SpiAttach as u8, spi_params.as_slice(), 0)
30+
connection.command(Command::SpiAttach, spi_params.as_slice(), 0)
3131
})?;
3232
Ok(())
3333
}

espflash/src/flash_target/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn begin_command(
6161
};
6262

6363
connection.with_timeout(command.timeout_for_size(size), |connection| {
64-
connection.command(command as u8, data, 0)?;
64+
connection.command(command, data, 0)?;
6565
Ok(())
6666
})
6767
}
@@ -120,7 +120,7 @@ fn block_command_with_timeout(
120120

121121
connection.with_timeout(timout, |connection| {
122122
connection.command(
123-
command as u8,
123+
command,
124124
(length as u16, |encoder: &mut Encoder| {
125125
encoder.write(bytes_of(&params))?;
126126
encoder.write(data)?;

espflash/src/flasher.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ const ERASE_WRITE_TIMEOUT_PER_MB: Duration = Duration::from_secs(40);
2828
const MEM_END_TIMEOUT: Duration = Duration::from_millis(50);
2929
const SYNC_TIMEOUT: Duration = Duration::from_millis(100);
3030

31-
#[derive(Copy, Clone, Debug)]
31+
#[derive(Copy, Clone, Debug, Display)]
3232
#[allow(dead_code)]
3333
#[repr(u8)]
34-
pub(crate) enum Command {
34+
#[non_exhaustive]
35+
pub enum Command {
36+
Unknown = 0,
3537
FlashBegin = 0x02,
3638
FlashData = 0x03,
3739
FlashEnd = 0x04,
@@ -48,6 +50,7 @@ pub(crate) enum Command {
4850
FlashDeflateData = 0x11,
4951
FlashDeflateEnd = 0x12,
5052
FlashMd5 = 0x13,
53+
FlashDetect = 0x9f,
5154
}
5255

5356
impl Command {
@@ -68,7 +71,9 @@ impl Command {
6871
)
6972
}
7073
match self {
71-
Command::FlashBegin => calc_timeout(ERASE_REGION_TIMEOUT_PER_MB, size),
74+
Command::FlashBegin | Command::FlashDeflateBegin => {
75+
calc_timeout(ERASE_REGION_TIMEOUT_PER_MB, size)
76+
}
7277
Command::FlashData | Command::FlashDeflateData => {
7378
calc_timeout(ERASE_WRITE_TIMEOUT_PER_MB, size)
7479
}
@@ -258,7 +263,7 @@ impl Flasher {
258263
}
259264

260265
fn flash_detect(&mut self) -> Result<bool, Error> {
261-
let flash_id = self.spi_command(0x9f, &[], 24)?;
266+
let flash_id = self.spi_command(Command::FlashDetect, &[], 24)?;
262267
let size_id = flash_id >> 16;
263268

264269
self.flash_size = FlashSize::from(size_id as u8)?;
@@ -340,7 +345,7 @@ impl Flasher {
340345

341346
self.connection
342347
.with_timeout(command.timeout_for_size(size), |connection| {
343-
connection.command(command as u8, data, 0)?;
348+
connection.command(command, data, 0)?;
344349
Ok(())
345350
})
346351
}
@@ -354,14 +359,14 @@ impl Flasher {
354359
let spi_params = spi_attach_params.encode();
355360
self.connection
356361
.with_timeout(Command::SpiAttach.timeout(), |connection| {
357-
connection.command(Command::SpiAttach as u8, spi_params.as_slice(), 0)
362+
connection.command(Command::SpiAttach, spi_params.as_slice(), 0)
358363
})?;
359364
}
360365
}
361366
Ok(())
362367
}
363368

364-
fn spi_command(&mut self, command: u8, data: &[u8], read_bits: u32) -> Result<u32, Error> {
369+
fn spi_command(&mut self, command: Command, data: &[u8], read_bits: u32) -> Result<u32, Error> {
365370
assert!(read_bits < 32);
366371
assert!(data.len() < 64);
367372

@@ -421,7 +426,7 @@ impl Flasher {
421426
}
422427
i += 1;
423428
if i > 10 {
424-
return Err(Error::Connection(ConnectionError::Timeout));
429+
return Err(Error::Connection(ConnectionError::Timeout(command.into())));
425430
}
426431
}
427432

@@ -435,7 +440,7 @@ impl Flasher {
435440
fn read_reg(&mut self, reg: u32) -> Result<u32, Error> {
436441
self.connection
437442
.with_timeout(Command::ReadReg.timeout(), |connection| {
438-
connection.command(Command::ReadReg as u8, &reg.to_le_bytes()[..], 0)
443+
connection.command(Command::ReadReg, &reg.to_le_bytes()[..], 0)
439444
})
440445
}
441446

@@ -448,7 +453,7 @@ impl Flasher {
448453
};
449454
self.connection
450455
.with_timeout(Command::WriteReg.timeout(), |connection| {
451-
connection.command(Command::WriteReg as u8, bytes_of(&params), 0)
456+
connection.command(Command::WriteReg, bytes_of(&params), 0)
452457
})?;
453458
Ok(())
454459
}
@@ -524,11 +529,7 @@ impl Flasher {
524529

525530
self.connection
526531
.with_timeout(Command::ChangeBaud.timeout(), |connection| {
527-
connection.command(
528-
Command::ChangeBaud as u8,
529-
&[new_speed, old_speed].concat()[..],
530-
0,
531-
)
532+
connection.command(Command::ChangeBaud, &[new_speed, old_speed].concat()[..], 0)
532533
})?;
533534
self.connection.set_baud(speed)?;
534535
std::thread::sleep(Duration::from_secs_f32(0.05));

0 commit comments

Comments
 (0)