Skip to content

Commit b5d1e01

Browse files
committed
Extract connection related code from Flasher into Connection, where it belongs
1 parent 112dad7 commit b5d1e01

File tree

2 files changed

+86
-84
lines changed

2 files changed

+86
-84
lines changed

espflash/src/connection.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::{
1515
error::{ConnectionError, Error, ResultExt, RomError, RomErrorKind},
1616
};
1717

18+
const DEFAULT_CONNECT_ATTEMPTS: usize = 7;
1819
const USB_SERIAL_JTAG_PID: u16 = 0x1001;
1920

2021
#[derive(Debug, Copy, Clone, BinRead)]
@@ -51,6 +52,75 @@ impl Connection {
5152
}
5253
}
5354

55+
pub fn begin(&mut self) -> Result<(), Error> {
56+
let mut extra_delay = false;
57+
for i in 0..DEFAULT_CONNECT_ATTEMPTS {
58+
if self.connect_attempt(extra_delay).is_err() {
59+
extra_delay = !extra_delay;
60+
61+
let delay_text = if extra_delay { "extra" } else { "default" };
62+
println!("Unable to connect, retrying with {} delay...", delay_text);
63+
} else {
64+
// Print a blank line if more than one connection attempt was made to visually
65+
// separate the status text and whatever comes next.
66+
if i > 0 {
67+
println!();
68+
}
69+
return Ok(());
70+
}
71+
}
72+
73+
Err(Error::Connection(ConnectionError::ConnectionFailed))
74+
}
75+
76+
fn connect_attempt(&mut self, extra_delay: bool) -> Result<(), Error> {
77+
self.reset_to_flash(extra_delay)?;
78+
79+
for _ in 0..5 {
80+
self.flush()?;
81+
if self.sync().is_ok() {
82+
return Ok(());
83+
}
84+
}
85+
86+
Err(Error::Connection(ConnectionError::ConnectionFailed))
87+
}
88+
89+
fn sync(&mut self) -> Result<(), Error> {
90+
self.with_timeout(CommandType::Sync.timeout(), |connection| {
91+
connection.write_command(Command::Sync)?;
92+
connection.flush()?;
93+
94+
for _ in 0..100 {
95+
match connection.read_response()? {
96+
Some(response) if response.return_op == CommandType::Sync as u8 => {
97+
if response.status == 1 {
98+
let _error = connection.flush();
99+
return Err(Error::RomError(RomError::new(
100+
CommandType::Sync,
101+
RomErrorKind::from(response.error),
102+
)));
103+
} else {
104+
break;
105+
}
106+
}
107+
_ => continue,
108+
}
109+
}
110+
111+
Ok(())
112+
})?;
113+
114+
for _ in 0..700 {
115+
match self.read_response()? {
116+
Some(_) => break,
117+
_ => continue,
118+
}
119+
}
120+
121+
Ok(())
122+
}
123+
54124
pub fn reset(&mut self) -> Result<(), Error> {
55125
sleep(Duration::from_millis(100));
56126

espflash/src/flasher.rs

Lines changed: 16 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@ use crate::{
99
command::{Command, CommandType},
1010
connection::Connection,
1111
elf::{FirmwareImage, RomSegment},
12-
error::{ConnectionError, FlashDetectError, ResultExt, RomError, RomErrorKind},
12+
error::{ConnectionError, FlashDetectError, ResultExt},
1313
image_format::ImageFormatId,
1414
Error, PartitionTable,
1515
};
1616

17-
const DEFAULT_CONNECT_ATTEMPTS: usize = 7;
1817
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3);
1918

2019
pub(crate) const FLASH_SECTOR_SIZE: usize = 0x1000;
@@ -178,17 +177,26 @@ impl Flasher {
178177
port_info: UsbPortInfo,
179178
speed: Option<u32>,
180179
) -> Result<Self, Error> {
180+
// Establish a connection to the device using the default baud rate of 115,200
181+
// and timeout of 3 seconds.
182+
let mut connection = Connection::new(serial, port_info);
183+
connection.begin()?;
184+
connection.set_timeout(DEFAULT_TIMEOUT)?;
185+
186+
// Detect which chip we are connected to.
187+
let magic = connection.read_reg(CHIP_DETECT_MAGIC_REG_ADDR)?;
188+
let chip = Chip::from_magic(magic)?;
189+
181190
let mut flasher = Flasher {
182-
connection: Connection::new(serial, port_info), // default baud is always 115200
183-
chip: Chip::Esp8266, // dummy, set properly later
191+
connection,
192+
chip,
184193
flash_size: FlashSize::Flash4Mb,
185-
spi_params: SpiAttachParams::default(), // may be set when trying to attach to flash
194+
spi_params: SpiAttachParams::default(),
186195
};
187-
flasher.start_connection()?;
188-
flasher.connection.set_timeout(DEFAULT_TIMEOUT)?;
189-
flasher.chip_detect()?;
190196
flasher.spi_autodetect()?;
191197

198+
// Now that we have established a connection and detected the chip and flash
199+
// size, we can set the baud rate of the connection to the configured value.
192200
if let Some(b) = speed {
193201
match flasher.chip {
194202
Chip::Esp8266 => (), // Not available
@@ -223,14 +231,6 @@ impl Flasher {
223231
Err(Error::FlashConnect)
224232
}
225233

226-
fn chip_detect(&mut self) -> Result<(), Error> {
227-
let magic = self.connection.read_reg(CHIP_DETECT_MAGIC_REG_ADDR)?;
228-
let chip = Chip::from_magic(magic)?;
229-
230-
self.chip = chip;
231-
Ok(())
232-
}
233-
234234
fn flash_detect(&mut self) -> Result<Option<FlashSize>, Error> {
235235
const FLASH_RETRY: u8 = 0xFF;
236236

@@ -257,74 +257,6 @@ impl Flasher {
257257
Ok(Some(flash_size))
258258
}
259259

260-
fn sync(&mut self) -> Result<(), Error> {
261-
self.connection
262-
.with_timeout(CommandType::Sync.timeout(), |connection| {
263-
connection.write_command(Command::Sync)?;
264-
connection.flush()?;
265-
266-
for _ in 0..100 {
267-
match connection.read_response()? {
268-
Some(response) if response.return_op == CommandType::Sync as u8 => {
269-
if response.status == 1 {
270-
let _error = connection.flush();
271-
return Err(Error::RomError(RomError::new(
272-
CommandType::Sync,
273-
RomErrorKind::from(response.error),
274-
)));
275-
} else {
276-
break;
277-
}
278-
}
279-
_ => continue,
280-
}
281-
}
282-
283-
Ok(())
284-
})?;
285-
for _ in 0..700 {
286-
match self.connection.read_response()? {
287-
Some(_) => break,
288-
_ => continue,
289-
}
290-
}
291-
Ok(())
292-
}
293-
294-
fn start_connection(&mut self) -> Result<(), Error> {
295-
let mut extra_delay = false;
296-
for i in 0..DEFAULT_CONNECT_ATTEMPTS {
297-
if self.connect_attempt(extra_delay).is_err() {
298-
extra_delay = !extra_delay;
299-
300-
let delay_text = if extra_delay { "extra" } else { "default" };
301-
println!("Unable to connect, retrying with {} delay...", delay_text);
302-
} else {
303-
// Print a blank line if more than one connection attempt was made to visually
304-
// separate the status text and whatever comes next.
305-
if i > 0 {
306-
println!();
307-
}
308-
return Ok(());
309-
}
310-
}
311-
312-
Err(Error::Connection(ConnectionError::ConnectionFailed))
313-
}
314-
315-
fn connect_attempt(&mut self, extra_delay: bool) -> Result<(), Error> {
316-
self.connection.reset_to_flash(extra_delay)?;
317-
318-
for _ in 0..5 {
319-
self.connection.flush()?;
320-
if self.sync().is_ok() {
321-
return Ok(());
322-
}
323-
}
324-
325-
Err(Error::Connection(ConnectionError::ConnectionFailed))
326-
}
327-
328260
fn enable_flash(&mut self, spi_params: SpiAttachParams) -> Result<(), Error> {
329261
match self.chip {
330262
Chip::Esp8266 => {

0 commit comments

Comments
 (0)