### Install espflash Application via cargo-binstall Source: https://docs.rs/espflash/latest/espflash/index Installs the espflash application using cargo-binstall, a faster alternative to standard Cargo installations. This command-line tool allows flashing Espressif devices. ```bash cargo binstall espflash ``` -------------------------------- ### Install espflash Application using cargo-binstall Source: https://docs.rs/espflash/latest/index Installs the espflash application using cargo-binstall, a faster binary installer for Rust crates. This is an alternative to the standard `cargo install`. ```bash $ cargo binstall espflash ``` -------------------------------- ### Rust: Example of TTYPort Pair Creation Source: https://docs.rs/espflash/latest/espflash/connection/type A basic example demonstrating how to create a pair of pseudo serial terminals using `TTYPort::pair()`. This is useful for testing or simulating serial communication. ```rust use serialport::TTYPort; let (mut master, mut slave) = TTYPort::pair().unwrap(); ``` -------------------------------- ### Install espflash Application via Cargo Source: https://docs.rs/espflash/latest/espflash/index Installs the espflash application using the Rust package manager, Cargo. This command-line tool allows flashing Espressif devices. ```bash cargo install espflash ``` -------------------------------- ### Install espflash Application using Cargo Source: https://docs.rs/espflash/latest/index Installs the espflash application using the Cargo package manager. This command-line tool is used for flashing Espressif devices. ```bash $ cargo install espflash ``` -------------------------------- ### Define FlashStub Structure and Load Configurations - Rust Source: https://docs.rs/espflash/latest/src/espflash/flasher/stubs Defines the `FlashStub` struct to hold flash stub details like entry point, base64 encoded text, text start address, base64 encoded data, and data start address. It includes a `get` method to fetch the appropriate stub for a given `Chip` by loading and parsing a TOML string. The `text` and `data` methods decode the base64 encoded strings and return the start address and byte vector. ```Rust use std::time::Duration; use base64::{Engine as _, engine::general_purpose}; use serde::{Deserialize, Serialize}; use crate::target::Chip; /// Flash stub object (deserialized from TOML, converted from JSON as used by /// `esptool.py`) #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct FlashStub { /// Entry point (address) entry: u32, /// Text (base64 encoded) text: String, /// Start of text section address text_start: u32, /// Data data: String, /// Start of data section address data_start: u32, } pub(crate) const CHIP_DETECT_MAGIC_REG_ADDR: u32 = 0x40001000; pub(crate) const DEFAULT_TIMEOUT: Duration = Duration::from_secs(3); pub(crate) const EXPECTED_STUB_HANDSHAKE: &str = "OHAI"; // Include stub objects in binary const STUB_32: &str = include_str!("../../resources/stubs/esp32.toml"); const STUB_32C2: &str = include_str!("../../resources/stubs/esp32c2.toml"); const STUB_32C3: &str = include_str!("../../resources/stubs/esp32c3.toml"); const STUB_32C5: &str = include_str!("../../resources/stubs/esp32c5.toml"); const STUB_32C6: &str = include_str!("../../resources/stubs/esp32c6.toml"); const STUB_32H2: &str = include_str!("../../resources/stubs/esp32h2.toml"); const STUB_32P4: &str = include_str!("../../resources/stubs/esp32p4.toml"); const STUB_32S2: &str = include_str!("../../resources/stubs/esp32s2.toml"); const STUB_32S3: &str = include_str!("../../resources/stubs/esp32s3.toml"); impl FlashStub { /// Fetch flash stub for the provided chip pub fn get(chip: Chip) -> FlashStub { let s = match chip { Chip::Esp32 => STUB_32, Chip::Esp32c2 => STUB_32C2, Chip::Esp32c3 => STUB_32C3, Chip::Esp32c5 => STUB_32C5, Chip::Esp32c6 => STUB_32C6, Chip::Esp32h2 => STUB_32H2, Chip::Esp32p4 => STUB_32P4, Chip::Esp32s2 => STUB_32S2, Chip::Esp32s3 => STUB_32S3, }; let stub: FlashStub = toml::from_str(s).unwrap(); stub } /// Fetch stub entry point pub fn entry(&self) -> u32 { self.entry } /// Fetch text start address and bytes pub fn text(&self) -> (u32, Vec) { let v = general_purpose::STANDARD.decode(&self.text).unwrap(); (self.text_start, v) } /// Fetch data start address and bytes pub fn data(&self) -> (u32, Vec) { let v = general_purpose::STANDARD.decode(&self.data).unwrap(); (self.data_start, v) } } ``` -------------------------------- ### Rust Implementation: Segment Creation and Manipulation Source: https://docs.rs/espflash/latest/espflash/image_format/struct Provides methods for creating new Segment instances, splitting segments, getting their size, accessing data, and padding for alignment. These are fundamental operations for managing code segments. ```rust pub fn new(addr: u32, data: &'a [u8]) -> Self pub fn split_off(&mut self, count: usize) -> Self pub fn size(&self) -> u32 pub fn data(&self) -> &[u8] pub fn pad_align(&mut self, align: usize) ``` -------------------------------- ### Rust SLIP Encoder Initialization and Finishing Source: https://docs.rs/espflash/latest/src/espflash/connection/mod Provides methods to create a new SLIP encoder context, initializing it with a starting END byte, and to finish the encoding process by appending a final END byte. It tracks the total number of bytes written. This functionality is crucial for establishing and concluding SLIP frames. ```rust impl<'a, W: Write> SlipEncoder<'a, W> { /// Creates a new encoder context. pub fn new(writer: &'a mut W) -> std::io::Result { let len = writer.write(&[END])?; Ok(Self { writer, len }) } /// Finishes the encoding. pub fn finish(mut self) -> std::io::Result { self.len += self.writer.write(&[END])?; Ok(self.len) } } ``` -------------------------------- ### Write Binary to Flash in Rust (Partial) Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Initiates the process of writing a binary image to the device's flash memory at a specific address. This snippet is a function signature and the start of the implementation. Further details on segment writing and completion are expected. Dependencies include `spi_registers` and `Connection`. ```rust pub fn write_bin_to_flash( &mut self, ``` -------------------------------- ### Create ESP Partition Table in Rust Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This code constructs a partition table for an ESP32 device using the `PartitionTable::new` constructor. It defines partitions for Non-Volatile Storage (NVS), PHY initialization data, and the application factory image, specifying their types, subtypes, addresses, and sizes. Dependencies include `Partition`, `Type`, `SubType`, `DataType`, `AppType`, and constants like `NVS_ADDR`, `NVS_SIZE`, `PHY_INIT_DATA_ADDR`, `PHY_INIT_DATA_SIZE`, and `MAX_PARTITION_SIZE`. ```rust PartitionTable::new(vec![ Partition::new( String::from("nvs"), Type::Data, SubType::Data(DataType::Nvs), NVS_ADDR, NVS_SIZE, Flags::empty(), ), Partition::new( String::from("phy_init"), Type::Data, SubType::Data(DataType::Phy), PHY_INIT_DATA_ADDR, PHY_INIT_DATA_SIZE, Flags::empty(), ), Partition::new( String::from("factory"), Type::App, SubType::App(AppType::Factory), app_addr, core::cmp::min( flash_size.map_or(app_size, |size| size - app_addr), MAX_PARTITION_SIZE, ), Flags::empty(), ), ]) ``` -------------------------------- ### Flasher Structure and Connect Method (Rust) Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod The Flasher struct manages the process of connecting to and flashing a target device. The `connect` method initializes the flasher, sets up the connection with specified parameters (like stub loader usage, verification, skipping, chip type, and baud rate), and returns a Flasher instance or an error. ```rust #[cfg(feature = "serialport")] #[derive(Debug)] pub struct Flasher { /// Connection for flash operations connection: Connection, /// Chip ID chip: Chip, /// Flash size, loaded from SPI flash flash_size: FlashSize, /// Configuration for SPI attached flash (0 to use fused values) spi_params: SpiAttachParams, /// Indicate RAM stub loader is in use use_stub: bool, /// Indicate verifying flash contents after flashing verify: bool, /// Indicate skipping of already flashed regions skip: bool, } #[cfg(feature = "serialport")] impl Flasher { /// The serial port's baud rate should be 115_200 to connect. After /// connecting, Flasher will change the baud rate to the `baud` /// parameter. pub fn connect( mut connection: Connection, use_stub: bool, verify: bool, skip: bool, chip: Option, baud: Option, ) -> Result { // The connection should already be established with the device using the ``` -------------------------------- ### Manage ESP Partition Table Selection Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This code handles the selection of the target application partition. It prioritizes a user-specified partition if provided, otherwise it defaults to the 'factory' partition or any available 'app' partition. It returns an error if no suitable partition is found. Dependencies include `PartitionTable`, `Type`, and custom `Error` enum. ```rust let target_app_partition: Partition = // Use the target app partition if provided if let Some(target_partition) = target_app_partition { partition_table .find(target_partition) .ok_or(Error::AppPartitionNotFound)? .clone() } else { // The default partition table contains the "factory" partition, and if a user // provides a partition table via command-line then the validation step confirms // that at least one "app" partition is present. We prefer the "factory" // partition, and use any available "app" partitions if not present. partition_table .find("factory") .or_else(|| partition_table.find_by_type(Type::App)) .ok_or(Error::AppPartitionNotFound)? .clone() }; ``` -------------------------------- ### Rust: Raw File Descriptor Access for TTYPort Source: https://docs.rs/espflash/latest/espflash/connection/type Enables accessing the raw file descriptor (fd) of a TTYPort. This includes methods to get the raw fd, construct a TTYPort from a raw fd, and consume the TTYPort to get the raw fd. ```rust impl AsRawFd for TTYPort fn as_raw_fd(&self) -> i32 ``` ```rust impl FromRawFd for TTYPort unsafe fn from_raw_fd(fd: i32) -> TTYPort ``` ```rust impl IntoRawFd for TTYPort fn into_raw_fd(self) -> i32 ``` -------------------------------- ### Get MD5 Checksum of Flash Region Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Retrieves the MD5 checksum for a specified region of flash memory. ```APIDOC ## GET /websites/rs_espflash/checksum_md5 ### Description Retrieves the MD5 checksum for a specified region of flash memory. ### Method GET ### Endpoint /websites/rs_espflash/checksum_md5 ### Parameters #### Path Parameters None #### Query Parameters - **addr** (u32) - Required - The starting address of the region. - **length** (u32) - Required - The length of the region in bytes. ### Request Example ```bash curl "http://your-api-domain.com/websites/rs_espflash/checksum_md5?addr=0x1000&length=1024" ``` ### Response #### Success Response (200) - **checksum** (u128) - The MD5 checksum of the specified region. #### Response Example ```json { "checksum": "a1b2c3d4e5f678901234567890abcdef" } ``` ``` -------------------------------- ### Rust: IdfBootloaderFormat::new constructor Source: https://docs.rs/espflash/latest/espflash/image_format/idf/struct Creates a new `IdfBootloaderFormat` instance. It takes raw data for the ELF, flash, partition table, and bootloader, along with optional offsets and target partition names. Returns a `Result` containing the `IdfBootloaderFormat` or an `Error`. ```rust pub fn new( elf_data: &'a [u8], flash_data: &FlashData, partition_table_path: Option<&Path>, bootloader_path: Option<&Path>, partition_table_offset: Option, target_app_partition: Option<&str>, ) -> Result ``` -------------------------------- ### Get Security Information Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Retrieves security information about the connected device. This method is deprecated and will be removed in a future release. ```APIDOC ## GET /websites/rs_espflash/security_info ### Description Retrieves security information about the connected device. This method is deprecated and will be removed in a future release. ### Method GET ### Endpoint /websites/rs_espflash/security_info ### Parameters #### Path Parameters None #### Query Parameters None ### Request Example ```bash curl "http://your-api-domain.com/websites/rs_espflash/security_info" ``` ### Response #### Success Response (200) - **SecurityInfo** (SecurityInfo) - An object containing security details. #### Response Example ```json { "security_level": "high", "secure_boot": true } ``` ``` -------------------------------- ### Generate Default ESP Partition Table Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This function generates a default partition table for ESP devices. It defines fixed addresses and sizes for NVS and PHY init data, and scales the app partition size based on the provided flash size. Dependencies include `Chip` and `PartitionTable`. ```rust fn default_partition_table(chip: Chip, flash_size: Option) -> PartitionTable { const NVS_ADDR: u32 = 0x9000; const NVS_SIZE: u32 = 0x6000; const PHY_INIT_DATA_ADDR: u32 = 0xf000; const PHY_INIT_DATA_SIZE: u32 = 0x1000; // ... implementation details for scaling and creating partitions ... ``` -------------------------------- ### Get eFuse Block Size Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the size of a specified eFuse block for the implementing target device. It uses chip-specific block size arrays. ```Rust pub fn block_size(&self, block: usize) -> u32 { match self { Chip::Esp32 => efuse::esp32::BLOCK_SIZES[block], Chip::Esp32c2 => efuse::esp32c2::BLOCK_SIZES[block], Chip::Esp32c3 => efuse::esp32c3::BLOCK_SIZES[block], Chip::Esp32c5 => efuse::esp32c5::BLOCK_SIZES[block], Chip::Esp32c6 => efuse::esp32c6::BLOCK_SIZES[block], Chip::Esp32h2 => efuse::esp32h2::BLOCK_SIZES[block], Chip::Esp32p4 => efuse::esp32p4::BLOCK_SIZES[block], Chip::Esp32s2 => efuse::esp32s2::BLOCK_SIZES[block], Chip::Esp32s3 => efuse::esp32s3::BLOCK_SIZES[block], } } ``` -------------------------------- ### Execute Flash Definition Begin Command in Rust Source: https://docs.rs/espflash/latest/src/espflash/target/flash_target/esp32 Initiates the compressed flashing process by sending the FlashDeflBegin command. This command specifies the total size, block count, block size, and offset for the data to be flashed. It also handles encryption support based on the chip type and stub usage. ```Rust connection.with_timeout( CommandType::FlashDeflBegin.timeout_for_size(erase_size), |connection| { connection.command(Command::FlashDeflBegin { size: segment.data.len() as u32, blocks: block_count as u32, block_size: flash_write_size as u32, offset: addr, supports_encryption: self.chip != Chip::Esp32 && !self.use_stub, })?; Ok(()) }, )?; ``` -------------------------------- ### Get Boot Address for ESP Chips Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the boot address for various ESP chip models. This is a direct mapping based on the chip type. ```Rust pub fn boot_address(&self) -> u32 { match self { Chip::Esp32c2 | Chip::Esp32c3 | Chip::Esp32c6 | Chip::Esp32h2 | Chip::Esp32s3 => 0x0, Chip::Esp32 | Chip::Esp32s2 => 0x1000, Chip::Esp32c5 | Chip::Esp32p4 => 0x2000, } } ``` -------------------------------- ### Get Default Crystal Frequency for ESP Chips Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the default crystal frequency for various ESP chip models. This affects the system clock speed. ```Rust pub fn default_xtal_frequency(&self) -> XtalFrequency { match self { Chip::Esp32c5 => XtalFrequency::_48Mhz, Chip::Esp32h2 => XtalFrequency::_32Mhz, _ => XtalFrequency::_40Mhz, } } ``` -------------------------------- ### Prepare and Align Application Segments for Flashing (Rust) Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This section prepares the application's flash and RAM segments for writing to the device. It merges adjacent segments to avoid overlaps and then pads them to ensure 4-byte alignment. The entry point, WP pin status, chip ID, and minimum chip revision are set in the image header. Dependencies include custom segment manipulation functions like `pad_align_segments` and `merge_adjacent_segments`, and ELf parsing. ```Rust // write the header of the app // use the same settings as the bootloader // just update the entry point header.entry = elf.elf_header().e_entry.get(Endianness::Little); header.wp_pin = WP_PIN_DISABLED; header.chip_id = flash_data.chip.id(); header.min_chip_rev_full = flash_data.min_chip_rev; header.append_digest = 1; let mut data = bytes_of(&header).to_vec(); // The bootloader needs segments to be 4-byte aligned, but ensuring that // alignment by padding segments might result in overlapping segments. We // need to merge adjacent segments first to avoid the possibility of them // overlapping, and then do the padding. let mut flash_segments: Vec<_> = pad_align_segments(merge_adjacent_segments( rom_segments(flash_data.chip, &elf).collect(), )); let mut ram_segments: Vec<_> = pad_align_segments(merge_adjacent_segments( ram_segments(flash_data.chip, &elf).collect(), )); let mut checksum = ESP_CHECKSUM_MAGIC; let mut segment_count = 0; // Find and bubble the app descriptor segment to the first position. We do this // after merging/padding the segments, so it should be okay to reorder them now. let app_desc_addr = if let Some(appdesc) = elf.section_by_name(".flash.appdesc") { let address = appdesc.address() as u32; let Some(segment_position) = flash_segments .iter_mut() .position(|s| s.addr <= address && s.addr + s.size() > address) else { ``` -------------------------------- ### Get Reset After Operation Setting in Rust Source: https://docs.rs/espflash/latest/src/espflash/connection/mod Returns the configured behavior for resetting the chip after an operation. This is an enum `ResetAfterOperation`. It indicates how the chip should be reset post-operation. ```Rust /// Returns the reset after operation. pub fn after_operation(&self) -> ResetAfterOperation { self.after_operation } ``` -------------------------------- ### Create IdfBootloaderFormat in Rust Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf The `new` function for `IdfBootloaderFormat` constructs a new instance by parsing an ELF file, reading partition table data (either from a file or a default), and handling flash data. It supports specifying paths for the partition table and bootloader, as well as an offset for the partition table. ```rust impl<'a> IdfBootloaderFormat<'a> { /// Create a new [`IdfBootloaderFormat`]. pub fn new( elf_data: &'a [u8], flash_data: &FlashData, partition_table_path: Option<&Path>, bootloader_path: Option<&Path>, partition_table_offset: Option, target_app_partition: Option<&str>, ) -> Result { let elf = ElfFile::parse(elf_data)?; let partition_table = if let Some(partition_table_path) = partition_table_path { let data = fs::read(partition_table_path) .map_err(|e| Error::FileOpenError(partition_table_path.display().to_string(), e))?; PartitionTable::try_from(data)? } else { default_partition_table( flash_data.chip, flash_data.flash_settings.size.map(|v| v.size()), ) }; if partition_table .partitions() .iter() .map(|p| p.size()) .sum::() ``` -------------------------------- ### Initialize Device Connection in Rust Source: https://docs.rs/espflash/latest/src/espflash/connection/mod This Rust code initializes a connection to a target device. It constructs a reset strategy sequence based on port information and before_operation settings. The code then iterates through connection attempts, retrying if an error occurs. If a connection is successfully established within the maximum attempts, it returns Ok. Otherwise, it returns a ConnectionFailed error. ```rust /// Initializes a connection with a device. pub fn begin(&mut self) -> Result<(), Error> { let port_name = self.serial.name().unwrap_or_default(); let reset_sequence = construct_reset_strategy_sequence( &port_name, self.port_info.pid, self.before_operation, ); for (_, reset_strategy) in zip(0..MAX_CONNECT_ATTEMPTS, reset_sequence.iter().cycle()) { match self.connect_attempt(reset_strategy.as_ref()) { Ok(_) => { return Ok(()); } Err(e) => { debug!("Failed to reset, error {e:#?}, retrying"); } } } Err(Error::Connection(Box::new( ConnectionError::ConnectionFailed, ))) } /// Connects to a device. fn connect_attempt(&mut self, reset_strategy: &dyn ResetStrategy) -> Result<(), Error> { // If we're doing no_sync, we're likely communicating as a pass through // with an intermediate device to the ESP32 if self.before_operation == ResetBeforeOperation::NoResetNoSync { return Ok(()); } let mut download_mode: bool = false; let mut boot_mode = String::new(); let mut boot_log_detected = false; let mut buff: Vec; ``` -------------------------------- ### Get eFuse Register Base Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the base address of the eFuse register for different ESP chip models. This address is used for accessing eFuse data. ```Rust pub fn efuse_reg(&self) -> u32 { match self { Chip::Esp32 => 0x3FF5_A000, Chip::Esp32c2 => 0x6000_8800, Chip::Esp32c3 => 0x6000_8800, Chip::Esp32c5 => 0x600B4800, Chip::Esp32c6 => 0x600B_0800, Chip::Esp32h2 => 0x600B_0800, Chip::Esp32p4 => 0x5012_D000, Chip::Esp32s2 => 0x3F41_A000, Chip::Esp32s3 => 0x6000_7000, } } ``` -------------------------------- ### Get Default Flash Frequency for ESP Chips Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the default flash frequency for different ESP chip models. This configuration is crucial for SPI flash operations. ```Rust pub fn default_flash_frequency(&self) -> FlashFrequency { match self { Chip::Esp32 | Chip::Esp32c3 | Chip::Esp32c5 | Chip::Esp32c6 | Chip::Esp32p4 | Chip::Esp32s2 | Chip::Esp32s3 => FlashFrequency::_40Mhz, Chip::Esp32c2 => FlashFrequency::_30Mhz, Chip::Esp32h2 => FlashFrequency::_24Mhz, } } ``` -------------------------------- ### Read and Prepare Bootloader for ESP Devices (Rust) Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This snippet reads a bootloader file from a given path or generates a default one based on chip and crystal frequency. It then parses the bootloader's image header, validates its magic number, and updates header fields like flash mode and frequency. Dependencies include `std::fs`, `Cow`, and custom error types. ```Rust let mut bootloader = if let Some(bootloader_path) = bootloader_path { let bootloader = fs::read(bootloader_path)?; Cow::Owned(bootloader) } else { let default_bootloader = default_bootloader(flash_data.chip, flash_data.xtal_freq)?; Cow::Borrowed(default_bootloader) }; // fetch the generated header from the bootloader let mut calc_bootloader_size = 0; let bootloader_header_size = size_of::(); calc_bootloader_size += bootloader_header_size; let mut header: ImageHeader = *from_bytes(&bootloader[0..bootloader_header_size]); if header.magic != ESP_MAGIC { return Err(Error::InvalidBootloader); } for _ in 0..header.segment_count { let segment: SegmentHeader = *from_bytes( &bootloader [calc_bootloader_size..calc_bootloader_size + size_of::()], ); calc_bootloader_size += segment.length as usize + size_of::(); } // update the header if a user has specified any custom arguments if let Some(mode) = flash_data.flash_settings.mode { header.flash_mode = mode as u8; } header.write_flash_config( flash_data.flash_settings.size.unwrap_or_default(), flash_data .flash_settings .freq .unwrap_or(flash_data.chip.default_flash_frequency()), flash_data.chip, )?; bootloader.to_mut().splice( 0..size_of::(), bytes_of(&header).iter().copied(), ); ``` -------------------------------- ### Rust: Get Flash Size in Bytes Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Returns the flash size in bytes for each variant of the FlashSize enum. This is useful for memory calculations and allocations. ```rust impl FlashSize { /// Returns the flash size in bytes pub const fn size(self) -> u32 { match self { FlashSize::_256Kb => 0x0040000, FlashSize::_512Kb => 0x0080000, FlashSize::_1Mb => 0x0100000, FlashSize::_2Mb => 0x0200000, FlashSize::_4Mb => 0x0400000, FlashSize::_8Mb => 0x0800000, FlashSize::_16Mb => 0x1000000, FlashSize::_32Mb => 0x2000000, FlashSize::_64Mb => 0x4000000, FlashSize::_128Mb => 0x8000000, FlashSize::_256Mb => 0x10000000, } } } ``` -------------------------------- ### Get Reset Before Operation Setting in Rust Source: https://docs.rs/espflash/latest/src/espflash/connection/mod Returns the configured behavior for resetting the chip before an operation. This is an enum `ResetBeforeOperation`. It dictates how the chip should be reset prior to an operation. ```Rust /// Returns the reset before operation. pub fn before_operation(&self) -> ResetBeforeOperation { self.before_operation } ``` -------------------------------- ### Rust: FlashSettings Struct and Methods Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Defines the FlashSettings struct, which holds optional configuration for flash mode, size, and frequency. It includes methods for creating default settings and new settings with specified values. ```rust /// Flash settings to use when flashing a device. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] #[non_exhaustive] pub struct FlashSettings { /// Flash mode. pub mode: Option, /// Flash size. pub size: Option, /// Flash frequency. #[serde(rename = "frequency")] pub freq: Option, } impl FlashSettings { /// Returns the default [FlashSettings] with all fields set to `None`. pub const fn default() -> Self { FlashSettings { mode: None, size: None, freq: None, } } /// Creates a new [FlashSettings] with the specified mode, size, and /// frequency. pub fn new( mode: Option, size: Option, freq: Option, ) -> Self { FlashSettings { mode, size, freq } } } ``` -------------------------------- ### Retrieve ESP Partition Table Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This function returns a clone of the partition table associated with the application. Dependencies include `PartitionTable`. ```rust pub fn partition_table(&self) -> PartitionTable { self.partition_table.clone() } ``` -------------------------------- ### Get SPI W0 Register Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Calculates and returns the memory address for the SPI W0 register. This offset is added to the base SPI register address to locate the register. ```rust /// Get the address of the W0 register. pub fn w0(&self) -> u32 { self.base + self.w0_offset } ``` -------------------------------- ### Create Esp32Target Instance Source: https://docs.rs/espflash/latest/espflash/target/struct Provides a constructor function `new` for creating an `Esp32Target`. This function takes parameters to configure the target chip, SPI attachment, and options for stub usage, verification, and skipping operations. It returns a new instance of `Esp32Target`. ```rust pub fn new( chip: Chip, spi_attach_params: SpiAttachParams, use_stub: bool, verify: bool, skip: bool, ) -> Self ``` -------------------------------- ### Get SPI USR1 Register Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Calculates and returns the memory address for the SPI User register 1 (USR1). It adds the `usr1_offset` to the base SPI register address. ```rust /// Get the address of the USR1 register. pub fn usr1(&self) -> u32 { self.base + self.usr1_offset } ``` -------------------------------- ### Get eFuse Block 0 Offset Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the offset of BLOCK0 relative to the eFuse base register address for various ESP chips. This is used in eFuse read operations. ```Rust pub fn block0_offset(&self) -> u32 { match self { Chip::Esp32 => 0x0, Chip::Esp32c2 => 0x35, Chip::Esp32c3 => 0x2D, Chip::Esp32c5 => 0x2C, Chip::Esp32c6 => 0x2C, Chip::Esp32h2 => 0x2C, Chip::Esp32p4 => 0x2C, Chip::Esp32s2 => 0x2C, Chip::Esp32s3 => 0x2D, } } ``` -------------------------------- ### Initialize ESP Connection and Detect Chip (Rust) Source: https://docs.rs/espflash/latest/src/espflash/flasher/mod Initializes a connection to an ESP device, sets a default timeout, and detects the connected chip. It handles chip mismatches and ensures the correct chip is identified before proceeding with flashing operations. Dependencies include `espflash` crate functionalities. ```Rust connection.begin()?; connection.set_timeout(DEFAULT_TIMEOUT)?; detect_sdm(&mut connection); let detected_chip = if connection.before_operation() != ResetBeforeOperation::NoResetNoSync { // Detect which chip we are connected to. let detected_chip = connection.detect_chip(use_stub)?; if let Some(chip) = chip { if chip != detected_chip { return Err(Error::ChipMismatch( chip.to_string(), detected_chip.to_string(), )); } } detected_chip } else if connection.before_operation() == ResetBeforeOperation::NoResetNoSync && chip.is_some() { chip.unwrap() } else { return Err(Error::ChipNotProvided); }; let mut flasher = Flasher { connection, chip: detected_chip, flash_size: FlashSize::_4Mb, spi_params: SpiAttachParams::default(), use_stub, verify, skip, }; if flasher.connection.before_operation() == ResetBeforeOperation::NoResetNoSync { return Ok(flasher); } if !flasher.connection.secure_download_mode { // Load flash stub if enabled. if use_stub { info!("Using flash stub"); flasher.load_stub()?; } // Flash size autodetection doesn't work in Secure Download Mode. flasher.spi_autodetect()?; } else if use_stub { warn!("Stub is not supported in Secure Download Mode, setting --no-stub"); flasher.use_stub = false; } // Now that we have established a connection and detected the chip and flash // size, we can set the baud rate of the connection to the configured value. if let Some(baud) = baud { if baud > 115_200 { warn!("Setting baud rate higher than 115,200 can cause issues"); flasher.change_baud(baud)?; } } Ok(flasher) ``` -------------------------------- ### Get MMU Page Sizes for ESP Chips Source: https://docs.rs/espflash/latest/src/espflash/target/mod Retrieves the valid MMU page sizes for specific ESP chip models. Returns None for chips not explicitly listed. ```Rust pub fn valid_mmu_page_sizes(self) -> Option<&'static [u32]> { match self { Chip::Esp32c2 => Some(&[16 * 1024, 32 * 1024, 64 * 1024]), Chip::Esp32c6 | Chip::Esp32h2 => Some(&[8 * 1024, 16 * 1024, 32 * 1024, 64 * 1024]), // TODO: Verify this is correct for Esp32c5 _ => None, } } ``` -------------------------------- ### Extract ESP Application Metadata Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf This function returns a HashMap containing metadata about the application image, specifically the application size and partition size. Dependencies include `HashMap`. ```rust pub fn metadata(&self) -> HashMap<&str, String> { HashMap::from([ ("app_size", self.app_size.to_string()), ("part_size", self.partition_table_size.to_string()), ]) } ``` -------------------------------- ### Rust Method: size Source: https://docs.rs/espflash/latest/espflash/flasher/enum Returns the flash size in bytes as a `u32`. This method can be called on any `FlashSize` variant to get its size in bytes, which is useful for memory calculations and allocations. ```rust pub const fn size(self) -> u32 ``` -------------------------------- ### Other Commands Source: https://docs.rs/espflash/latest/src/espflash/command Miscellaneous commands including Sync, FlashDetect, and GetSecurityInfo. ```APIDOC ## POST /sync ### Description Synchronizes communication with the device. This is often used to establish or maintain a connection. ### Method POST ### Endpoint /sync ### Response #### Success Response (200) - **status** (string) - Indicates a successful synchronization. #### Response Example ```json { "status": "ok" } ``` ## POST /flash_detect ### Description Reads the manufacturer and device ID of the SPI flash. Note: This command is not part of the standard serial protocol. ### Method POST ### Endpoint /flash_detect ### Response #### Success Response (200) - **manufacturer_id** (u32) - The manufacturer ID of the flash chip. - **device_id** (u32) - The device ID of the flash chip. #### Response Example ```json { "manufacturer_id": 1, "device_id": 2 } ``` ## POST /get_security_info ### Description Retrieves security information from the chip. Note: This command is not supported by ESP32. ### Method POST ### Endpoint /get_security_info ### Response #### Success Response (200) - **info** (object) - An object containing security information (structure depends on the chip). #### Response Example ```json { "info": { "secure_boot_enabled": false } } ``` ``` -------------------------------- ### Get SPI USR2 Register Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Calculates and returns the memory address for the SPI User register 2 (USR2). This is done by adding the `usr2_offset` to the base SPI register address. ```rust /// Get the address of the USR2 register. pub fn usr2(&self) -> u32 { self.base + self.usr2_offset } ``` -------------------------------- ### Get USB PID in Rust Source: https://docs.rs/espflash/latest/src/espflash/connection/mod Retrieves the USB Product ID (PID) of the serial port. This information can be used to identify the connected device. Returns a `u16` representing the PID. ```Rust /// Returns the USB PID of the serial port. pub fn usb_pid(&self) -> u16 { self.port_info.pid } ``` -------------------------------- ### Device Configuration and Control Source: https://docs.rs/espflash/latest/src/espflash/command Commands for configuring SPI flash parameters, changing the baud rate, and controlling device execution. ```APIDOC ## POST /spi/set_params ### Description Configures the SPI flash parameters for the device. ### Method POST ### Endpoint /spi/set_params ### Parameters #### Request Body - **spi_params** (object) - Required - An object containing SPI parameters. - **spi_mode** (u32) - SPI mode. - **spi_speed** (u32) - SPI speed. - **spi_size** (u32) - SPI flash size. ### Request Example ```json { "spi_params": { "spi_mode": 0, "spi_speed": 40000000, "spi_size": 4194304 } } ``` ### Response #### Success Response (200) - **status** (string) - Indicates the success of the operation. #### Response Example ```json { "status": "ok" } ``` ## POST /spi/attach ### Description Attaches the SPI flash device to the system. ### Method POST ### Endpoint /spi/attach ### Parameters #### Request Body - **spi_params** (object) - Required - An object containing SPI attachment parameters. - **io_mode** (u32) - I/O mode. - **wp_pin** (i8) - Write protect pin. - **cs_pin** (i8) - Chip select pin. ### Request Example ```json { "spi_params": { "io_mode": 3, "wp_pin": -1, "cs_pin": 10 } } ``` ### Response #### Success Response (200) - **status** (string) - Indicates the success of the attachment. #### Response Example ```json { "status": "ok" } ``` ## POST /change_baudrate ### Description Changes the baud rate of the serial communication. ### Method POST ### Endpoint /change_baudrate ### Parameters #### Request Body - **new_baud** (u32) - Required - The new baud rate to set. - **prior_baud** (u32) - Required - The prior baud rate (use '0' for ROM flasher). ### Request Example ```json { "new_baud": 115200, "prior_baud": 0 } ``` ### Response #### Success Response (200) - **status** (string) - Indicates the success of the baud rate change. #### Response Example ```json { "status": "ok" } ``` ## POST /run_user_code ### Description Exits the current loader and begins execution of the user-uploaded code. ### Method POST ### Endpoint /run_user_code ### Response #### Success Response (200) - **status** (string) - Indicates that the command was processed. #### Response Example ```json { "status": "ok" } ``` ``` -------------------------------- ### Get SPI USR Register Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Calculates and returns the memory address for the SPI User register (USR). This is achieved by adding the `usr_offset` to the base address stored within the `SpiRegisters` struct. ```rust /// Get the address of the USR register. pub fn usr(&self) -> u32 { self.base + self.usr_offset } ``` -------------------------------- ### Get Default ESP-IDF Bootloader - Rust Source: https://docs.rs/espflash/latest/src/espflash/image_format/idf Retrieves the default bootloader binary for a given ESP-IDF chip and crystal frequency. This function maps chip types and their supported crystal frequencies to the corresponding static bootloader byte arrays. It returns an error if the specified crystal frequency is not supported for the given chip. ```rust const ESP_CHECKSUM_MAGIC: u8 = 0xEF; const ESP_MAGIC: u8 = 0xE9; const IROM_ALIGN: u32 = 0x10000; const SEG_HEADER_LEN: u32 = 8; const WP_PIN_DISABLED: u8 = 0xEE; /// Max partition size is 16 MB const MAX_PARTITION_SIZE: u32 = 16 * 1000 * 1024; const BOOTLOADER_ESP32_26MHZ: &[u8] = include_bytes!("../../resources/bootloaders/esp32_26-bootloader.bin"); const BOOTLOADER_ESP32_40MHZ: &[u8] = include_bytes!("../../resources/bootloaders/esp32-bootloader.bin"); const BOOTLOADER_ESP32C2_26MHZ: &[u8] = include_bytes!("../../resources/bootloaders/esp32c2_26-bootloader.bin"); const BOOTLOADER_ESP32C2_40MHZ: &[u8] = include_bytes!("../../resources/bootloaders/esp32c2-bootloader.bin"); const BOOTLOADER_ESP32C3: &[u8] = include_bytes!("../../resources/bootloaders/esp32c3-bootloader.bin"); const BOOTLOADER_ESP32C5: &[u8] = include_bytes!("../../resources/bootloaders/esp32c5-bootloader.bin"); const BOOTLOADER_ESP32C6: &[u8] = include_bytes!("../../resources/bootloaders/esp32c6-bootloader.bin"); const BOOTLOADER_ESP32H2: &[u8] = include_bytes!("../../resources/bootloaders/esp32h2-bootloader.bin"); const BOOTLOADER_ESP32P4: &[u8] = include_bytes!("../../resources/bootloaders/esp32p4-bootloader.bin"); const BOOTLOADER_ESP32S2: &[u8] = include_bytes!("../../resources/bootloaders/esp32s2-bootloader.bin"); const BOOTLOADER_ESP32S3: &[u8] = include_bytes!("../../resources/bootloaders/esp32s3-bootloader.bin"); /// Get the default bootloader for the given chip and crystal frequency pub(crate) fn default_bootloader( chip: Chip, xtal_freq: XtalFrequency, ) -> Result<&'static [u8], Error> { let error = Error::UnsupportedFeature { chip, feature: "the selected crystal frequency".into(), }; match chip { Chip::Esp32 => match xtal_freq { XtalFrequency::_26Mhz => Ok(BOOTLOADER_ESP32_26MHZ), XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32_40MHZ), _ => Err(error), }, Chip::Esp32c2 => match xtal_freq { XtalFrequency::_26Mhz => Ok(BOOTLOADER_ESP32C2_26MHZ), XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32C2_40MHZ), _ => Err(error), }, Chip::Esp32c3 => match xtal_freq { XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32C3), _ => Err(error), }, Chip::Esp32c5 => match xtal_freq { XtalFrequency::_40Mhz | XtalFrequency::_48Mhz => Ok(BOOTLOADER_ESP32C5), _ => Err(error), }, Chip::Esp32c6 => match xtal_freq { XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32C6), _ => Err(error), }, Chip::Esp32h2 => match xtal_freq { XtalFrequency::_32Mhz => Ok(BOOTLOADER_ESP32H2), _ => Err(error), }, Chip::Esp32p4 => match xtal_freq { XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32P4), _ => Err(error), }, Chip::Esp32s2 => match xtal_freq { XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32S2), _ => Err(error), }, Chip::Esp32s3 => match xtal_freq { XtalFrequency::_40Mhz => Ok(BOOTLOADER_ESP32S3), _ => Err(error), }, } } ``` -------------------------------- ### Get SPI Register Base Address Source: https://docs.rs/espflash/latest/src/espflash/target/mod Returns the base memory address for SPI registers. This method is part of the `SpiRegisters` struct, which holds offset information for various SPI control registers. ```rust /// Get the base address of the SPI registers. pub fn cmd(&self) -> u32 { self.base } ``` -------------------------------- ### Create RAM Target Source: https://docs.rs/espflash/latest/src/espflash/target/mod Creates and returns a new FlashTarget for RamTarget, configured with an optional entry point and maximum RAM block size. Requires the 'serialport' feature. ```Rust #[cfg(feature = "serialport")] pub fn ram_target( &self, entry: Option, max_ram_block_size: usize, ) -> Box { Box::new(RamTarget::new(entry, max_ram_block_size)) } ```