fn erase_device(
    device_id: u64,
    file_path: &std::path::Path,
    message_sender: &std::sync::mpsc::Sender<Message>,
) -> Result<()> {
    // Set the step so UI knows it
    message_sender
        .send(Message::DeviceUpdateStep(DeviceUpdateStep::Erase))
        .ok();

    // Find the device by its id and open it
    let mut device = dfudev::DfuDevice::find_by_id(device_id)?.unwrap();
    device.open()?;

    // Make sure device is in idle state before operations start
    device.abort_request()?;

    // Make sure status is OK
    while let Ok(status) = device.getstatus_request() {
        if status.bStatus == dfudev::DeviceStatusCode::OK {
            break;
        } else {
            device.clrstatus_request()?;
        }
    }

    let file = dfufile::DfuFile::open(file_path)?;

    match &file.content {
        dfufile::Content::Plain => {
            log::warn!("Plain DFU does not support separate erase. Skipped.");
        }
        dfufile::Content::DfuSe(content) => {
            let num_images = content.images.len();

            for (image_no, image) in content.images.iter().enumerate() {
                let alt_setting = image.target_prefix.bAlternateSetting;
                let target = device
                    .info
                    .alt_settings
                    .iter()
                    .find(|&alt| alt.0 == alt_setting);

                if let Some(target) = target {
                    let memory_segment = dfudev::dfuse::MemorySegment::from_string_desc(&target.1);
                    log::debug!(
                        "Found target \"{}\" for alt setting {}",
                        memory_segment.name,
                        target.0,
                    );

                    let num_elements = image.image_elements.len();

                    for (element_no, element) in image.image_elements.iter().enumerate() {
                        log::debug!(
                            "Reading element at address 0x{:08X}, size {}",
                            element.dwElementAddress,
                            element.dwElementSize
                        );
                        let start_address = element.dwElementAddress;
                        let end_address = start_address + element.dwElementSize;
                        let region = memory_segment.regions.iter().find(|x| {
                            x.start_address <= start_address
                                && x.end_address >= end_address
                                && x.erasable
                        });

                        if let Some(region) = region {
                            let sector_size = region.sector_size;
                            let num_sectors = (end_address - start_address) / sector_size;
                            log::debug!("Memory region found, sector size is {}", sector_size);
                            let mut erase_address = start_address / sector_size * sector_size;
                            let mut sector_no = 0;

                            while erase_address <= end_address {
                                log::debug!("Erasing sector at 0x{:08X}", erase_address);

                                dfudev::dfuse::erase_page(&device, erase_address)?;

                                let progress = (sector_no as f32) / (num_sectors as f32)
                                    * ((image_no + 1) as f32)
                                    / (num_images as f32)
                                    * ((element_no + 1) as f32)
                                    / (num_elements as f32);
                                message_sender
                                    .send(Message::DeviceEraseProgress(progress))
                                    .ok();

                                erase_address += sector_size;
                                sector_no += 1;
                            }
                        } else {
                            return Err(Box::new(Error::MemoryRegionNotFound(
                                start_address,
                                end_address,
                            )));
                        }
                    }
                } else {
                    return Err(Box::new(Error::TargetNotFound(alt_setting)));
                }
            }
        }
    }

    // Final cleanup
    device.abort_request()?;
    device.close();

    Ok(())
}
/// Erase the data in the device.
Erase the data in the device.
Erase the data in the device .
fn erase_device(
    device_id: u64,
    file_path: &std::path::Path,
    message_sender: &std::sync::mpsc::Sender<Message>,
) -> Result<()> {
    // Set the step so UI knows it
    message_sender
        .send(Message::DeviceUpdateStep(DeviceUpdateStep::Erase))
        .ok();
    // Find the device by its id and open it
    let mut device = dfudev::DfuDevice::find_by_id(device_id)?.unwrap();
    device.open()?;
    // Make sure device is in idle state before operations start
    device.abort_request()?;
    // Make sure status is OK
    while let Ok(status) = device.getstatus_request() {
        if status.bStatus == dfudev::DeviceStatusCode::OK {
            break;
        } else {
            device.clrstatus_request()?;
        }
    }
    let file = dfufile::DfuFile::open(file_path)?;
    match &file.content {
        dfufile::Content::Plain => {
            log::warn!("Plain DFU does not support separate erase. Skipped.");
        }
        dfufile::Content::DfuSe(content) => {
            let num_images = content.images.len();
            for (image_no, image) in content.images.iter().enumerate() {
                let alt_setting = image.target_prefix.bAlternateSetting;
                let target = device
                    .info
                    .alt_settings
                    .iter()
                    .find(|&alt| alt.0 == alt_setting);
                if let Some(target) = target {
                    let memory_segment = dfudev::dfuse::MemorySegment::from_string_desc(&target.1);
                    log::debug!(
                        "Found target \"{}\" for alt setting {}",
                        memory_segment.name,
                        target.0,
                    );
                    let num_elements = image.image_elements.len();
                    for (element_no, element) in image.image_elements.iter().enumerate() {
                        log::debug!(
                            "Reading element at address 0x{:08X}, size {}",
                            element.dwElementAddress,
                            element.dwElementSize
                        );
                        let start_address = element.dwElementAddress;
                        let end_address = start_address + element.dwElementSize;
                        let region = memory_segment.regions.iter().find(|x| {
                            x.start_address <= start_address
                                && x.end_address >= end_address
                                && x.erasable
                        });
                        if let Some(region) = region {
                            let sector_size = region.sector_size;
                            let num_sectors = (end_address - start_address) / sector_size;
                            log::debug!("Memory region found, sector size is {}", sector_size);
                            let mut erase_address = start_address / sector_size * sector_size;
                            let mut sector_no = 0;
                            while erase_address <= end_address {
                                log::debug!("Erasing sector at 0x{:08X}", erase_address);
                                dfudev::dfuse::erase_page(&device, erase_address)?;
                                let progress = (sector_no as f32) / (num_sectors as f32)
                                    * ((image_no + 1) as f32)
                                    / (num_images as f32)
                                    * ((element_no + 1) as f32)
                                    / (num_elements as f32);
                                message_sender
                                    .send(Message::DeviceEraseProgress(progress))
                                    .ok();
                                erase_address += sector_size;
                                sector_no += 1;
                            }
                        } else {
                            return Err(Box::new(Error::MemoryRegionNotFound(
                                start_address,
                                end_address,
                            )));
                        }
                    }
                } else {
                    return Err(Box::new(Error::TargetNotFound(alt_setting)));
                }
            }
        }
    }
    // Final cleanup
    device.abort_request()?;
    device.close();
    Ok(())
}
fn erase_device ( device_id : u64 , file_path : & std :: path :: Path , message_sender : & std :: sync :: mpsc :: Sender < Message > , ) -> Result < ( ) > { // Set the step so UI knows it message_sender . send ( Message :: DeviceUpdateStep ( DeviceUpdateStep :: Erase ) ) . ok ( ) ; // Find the device by its id and open it let mut device = dfudev :: DfuDevice :: find_by_id ( device_id ) ? . unwrap ( ) ; device . open ( ) ? ; // Make sure device is in idle state before operations start device . abort_request ( ) ? ; // Make sure status is OK while let Ok ( status ) = device . getstatus_request ( ) { if status . bStatus == dfudev :: DeviceStatusCode :: OK { break ; } else { device . clrstatus_request ( ) ? ; } } let file = dfufile :: DfuFile :: open ( file_path ) ? ; match & file . content { dfufile :: Content :: Plain => { log :: warn ! ( " " ) ; } dfufile :: Content :: DfuSe ( content ) => { let num_images = content . images . len ( ) ; for ( image_no , image ) in content . images . iter ( ) . enumerate ( ) { let alt_setting = image . target_prefix . bAlternateSetting ; let target = device . info . alt_settings . iter ( ) . find ( | & alt | alt . 0 == alt_setting ) ; if let Some ( target ) = target { let memory_segment = dfudev :: dfuse :: MemorySegment :: from_string_desc ( & target . 1 ) ; log :: debug ! ( " \" \" " memory_segment name target 0 ) ; let num_elements = image . image_elements . len ( ) ; for ( element_no , element ) in image . image_elements . iter ( ) . enumerate ( ) { log :: debug ! ( " " element dwElementAddress element dwElementSize ) ; let start_address = element . dwElementAddress ; let end_address = start_address + element . dwElementSize ; let region = memory_segment . regions . iter ( ) . find ( | x | { x . start_address <= start_address && x . end_address >= end_address && x . erasable } ) ; if let Some ( region ) = region { let sector_size = region . sector_size ; let num_sectors = ( end_address - start_address ) / sector_size ; log :: debug ! ( " " sector_size ) ; let mut erase_address = start_address / sector_size * sector_size ; let mut sector_no = 0 ; while erase_address <= end_address { log :: debug ! ( " " erase_address ) ; dfudev :: dfuse :: erase_page ( & device , erase_address ) ? ; let progress = ( sector_no as f32 ) / ( num_sectors as f32 ) * ( ( image_no + 1 ) as f32 ) / ( num_images as f32 ) * ( ( element_no + 1 ) as f32 ) / ( num_elements as f32 ) ; message_sender . send ( Message :: DeviceEraseProgress ( progress ) ) . ok ( ) ; erase_address += sector_size ; sector_no += 1 ; } } else { return Err ( Box :: new ( Error :: MemoryRegionNotFound ( start_address , end_address , ) ) ) ; } } } else { return Err ( Box :: new ( Error :: TargetNotFound ( alt_setting ) ) ) ; } } } } // Final cleanup device . abort_request ( ) ? ; device . close ( ) ; Ok ( ( ) ) }
Erase the data in the device.
Erase the data in the device .
device_id
u64
file_path
&std::path::Path
message_sender
&std::sync::mpsc::Sender<Message>