Skip to content

Commit ad0b6d6

Browse files
committed
Cut off the write_bin part from original esp-rs#832
1 parent 79bbd67 commit ad0b6d6

File tree

4 files changed

+55
-19
lines changed

4 files changed

+55
-19
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
234234
- Make the default flashing frequency target specific (#389)
235235
- Add note about permissions on Linux (#391)
236236
- Add a diagnostic to tell the user about the partition table format (#397)
237+
- Add (some level of) SDM support (#832)
237238

238239
### Fixed
239240

espflash/src/cli/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -575,17 +575,21 @@ pub fn parse_chip_rev(chip_rev: &str) -> Result<u16> {
575575
/// Print information about a chip
576576
pub fn print_board_info(flasher: &mut Flasher) -> Result<()> {
577577
let info = flasher.device_info()?;
578-
579578
print!("Chip type: {}", info.chip);
579+
580580
if let Some((major, minor)) = info.revision {
581581
println!(" (revision v{major}.{minor})");
582582
} else {
583583
println!();
584584
}
585+
585586
println!("Crystal frequency: {}", info.crystal_frequency);
586587
println!("Flash size: {}", info.flash_size);
587588
println!("Features: {}", info.features.join(", "));
588-
println!("MAC address: {}", info.mac_address);
589+
590+
if let Some(mac) = info.mac_address {
591+
println!("MAC address: {}", mac);
592+
}
589593

590594
Ok(())
591595
}

espflash/src/connection/mod.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ pub struct Connection {
124124
decoder: SlipDecoder,
125125
after_operation: ResetAfterOperation,
126126
before_operation: ResetBeforeOperation,
127+
pub(crate) secure_download_mode: bool,
127128
}
128129

129130
impl Connection {
@@ -139,11 +140,12 @@ impl Connection {
139140
decoder: SlipDecoder::new(),
140141
after_operation,
141142
before_operation,
143+
secure_download_mode: false,
142144
}
143145
}
144146

145147
/// Initialize a connection with a device
146-
pub fn begin(&mut self) -> Result<(), Error> {
148+
pub fn begin(&mut self) -> Result<bool, Error> {
147149
let port_name = self.serial.name().unwrap_or_default();
148150
let reset_sequence = construct_reset_strategy_sequence(
149151
&port_name,
@@ -154,7 +156,14 @@ impl Connection {
154156
for (_, reset_strategy) in zip(0..MAX_CONNECT_ATTEMPTS, reset_sequence.iter().cycle()) {
155157
match self.connect_attempt(reset_strategy) {
156158
Ok(_) => {
157-
return Ok(());
159+
match self.read_reg(crate::flasher::stubs::CHIP_DETECT_MAGIC_REG_ADDR) {
160+
Ok(_) => return Ok(false),
161+
Err(_) => {
162+
log::warn!("Secure Download Mode is enabled on this chip");
163+
self.secure_download_mode = true;
164+
return Ok(true);
165+
}
166+
};
158167
}
159168
Err(e) => {
160169
debug!("Failed to reset, error {:#?}, retrying", e);
@@ -449,6 +458,7 @@ impl Connection {
449458
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#response-packet
450459
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#status-bytes
451460
// - https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/serial-protocol.html?highlight=md5#verifying-uploaded-data
461+
452462
let status_len = if response.len() == 10 || response.len() == 26 {
453463
2
454464
} else {
@@ -483,8 +493,8 @@ impl Connection {
483493
return_op: response[1],
484494
return_length: u16::from_le_bytes(response[2..][..2].try_into().unwrap()),
485495
value,
486-
error: response[response.len() - status_len],
487-
status: response[response.len() - status_len + 1],
496+
error: response[response.len() - status_len + 1],
497+
status: response[response.len() - status_len],
488498
};
489499

490500
Ok(Some(header))
@@ -524,11 +534,10 @@ impl Connection {
524534
pub fn command(&mut self, command: Command<'_>) -> Result<CommandResponseValue, Error> {
525535
let ty = command.command_type();
526536
self.write_command(command).for_command(ty)?;
527-
528537
for _ in 0..100 {
529538
match self.read_response().for_command(ty)? {
530539
Some(response) if response.return_op == ty as u8 => {
531-
return if response.error != 0 {
540+
return if response.status != 0 {
532541
let _error = self.flush();
533542
Err(Error::RomError(RomError::new(
534543
command.command_type(),

espflash/src/flasher/mod.rs

+33-11
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ pub struct DeviceInfo {
634634
/// Device features
635635
pub features: Vec<String>,
636636
/// MAC address
637-
pub mac_address: String,
637+
pub mac_address: Option<String>,
638638
}
639639

640640
/// Connect to and flash a target device
@@ -674,7 +674,7 @@ impl Flasher {
674674
// Establish a connection to the device using the default baud rate of 115,200
675675
// and timeout of 3 seconds.
676676
let mut connection = Connection::new(serial, port_info, after_operation, before_operation);
677-
connection.begin()?;
677+
let sdm = connection.begin()?;
678678
connection.set_timeout(DEFAULT_TIMEOUT)?;
679679

680680
let detected_chip = if before_operation != ResetBeforeOperation::NoResetNoSync {
@@ -710,14 +710,19 @@ impl Flasher {
710710
return Ok(flasher);
711711
}
712712

713-
// Load flash stub if enabled
714-
if use_stub {
715-
info!("Using flash stub");
716-
flasher.load_stub()?;
713+
if !sdm {
714+
// Load flash stub if enabled.
715+
if use_stub {
716+
info!("Using flash stub");
717+
flasher.load_stub()?;
718+
}
719+
// Flash size autodetection doesn't work in Secure Download Mode.
720+
flasher.spi_autodetect()?;
721+
} else if use_stub {
722+
warn!("Stub is not supported in Secure Download Mode, setting --no-stub");
723+
flasher.use_stub = false;
717724
}
718725

719-
flasher.spi_autodetect()?;
720-
721726
// Now that we have established a connection and detected the chip and flash
722727
// size, we can set the baud rate of the connection to the configured value.
723728
if let Some(baud) = speed {
@@ -985,14 +990,21 @@ impl Flasher {
985990
let chip = self.chip();
986991
let target = chip.into_target();
987992

988-
let revision = Some(target.chip_revision(self.connection())?);
993+
// chip_revision reads from efuse, which is not possible in Secure Download Mode
994+
let revision = (!self.connection.secure_download_mode)
995+
.then(|| target.chip_revision(self.connection()))
996+
.transpose()?;
997+
989998
let crystal_frequency = target.crystal_freq(self.connection())?;
990999
let features = target
9911000
.chip_features(self.connection())?
9921001
.iter()
9931002
.map(|s| s.to_string())
9941003
.collect::<Vec<_>>();
995-
let mac_address = target.mac_address(self.connection())?;
1004+
1005+
let mac_address = (!self.connection.secure_download_mode)
1006+
.then(|| target.mac_address(self.connection()))
1007+
.transpose()?;
9961008

9971009
let info = DeviceInfo {
9981010
chip,
@@ -1102,10 +1114,20 @@ impl Flasher {
11021114
let mut target = self
11031115
.chip
11041116
.flash_target(self.spi_params, self.use_stub, false, false);
1117+
11051118
target.begin(&mut self.connection).flashing()?;
1119+
11061120
for segment in segments {
1107-
target.write_segment(&mut self.connection, segment.borrow(), &mut progress)?;
1121+
if self.connection.secure_download_mode {
1122+
return Err(Error::UnsupportedFeature {
1123+
chip: self.chip,
1124+
feature: "writing binaries in Secure Download Mode currently".into(),
1125+
});
1126+
} else {
1127+
target.write_segment(&mut self.connection, segment.borrow(), &mut progress)?;
1128+
}
11081129
}
1130+
11091131
target.finish(&mut self.connection, true).flashing()?;
11101132

11111133
Ok(())

0 commit comments

Comments
 (0)