/// Uploads the given buffer of data into the given address on the ATSAM.
///
/// Due to the nature of the SAM-BA and Flash on the ATSAM, there are several steps:
///
/// 1) Upload a copy applet into the device's RAM using the SAM Boot Assistant (SAM-BA).
/// 2) While there is more data to flash:
///    a) Upload a 512-byte page of the firmware into RAM using the SAM-BA
///    b) Configure the copy applet to copy the page to an address in internal flash
///    c) Use SAM-BA to execute the copy applet
Uploads the given buffer of data into the given address on the ATSAM.
Due to the nature of the SAM-BA and Flash on the ATSAM, there are several steps.

1) Upload a copy applet into the device's RAM using the SAM Boot Assistant (SAM-BA).
2) While there is more data to flash:
a) Upload a 512-byte page of the firmware into RAM using the SAM-BA
b) Configure the copy applet to copy the page to an address in internal flash
c) Use SAM-BA to execute the copy applet
Uploads the given buffer of data into the given address on the ATSAM . Due to the nature of the SAM - BA and Flash on the ATSAM there are several steps . 1 ) Upload a copy applet into the device ' s RAM using the SAM Boot Assistant ( SAM - BA ) . 2 ) While there is more data to flash : a ) Upload a 512 - byte page of the firmware into RAM using the SAM - BA b ) Configure the copy applet to copy the page to an address in internal flash c ) Use SAM - BA to execute the copy applet
fn upload(&mut self, destination: u32, data: &[u8]) {
        info!("Uploading {} byte image to address 0x{:08X}", data.len(), destination);
        let result = (||{
            self.enter_update_mode()?;
            self.enter_normal_mode()?;
            // Check the device's security bit
            self.write_efc_fcr(EFC_GGPB, 0x0)?;
            let word = self.read_word(EEFC_FRR)?;
            if word & 0x01 != 0 { Err(FdfuError::SecurityBit)? }
            // Write the copy applet into RAM
            self.copy(APPLET_ADDR, self.applet)?;
            let _ = self.sender.send(Progress::Applet);
            // Configure the applet's stack, entry point, destination, and source
            self.write_word(APPLET_STACK, IRAM_ADDR + IRAM_SIZE)?;
            self.write_word(APPLET_ENTRY, APPLET_ADDR + 0x09)?;
            self.write_word(APPLET_DESTINATION, destination)?;
            self.write_word(APPLET_SOURCE, PAGE_BUFFER(self.applet.len()))?;
            // Send the firmware, page by page
            let page_size = 512;
            for (i, page) in data.chunks(page_size).enumerate() {
                debug!("Writing page {}", i);
                self.copy(PAGE_BUFFER(self.applet.len()), page)?;
                self.write_word(APPLET_PAGE, EEFC_FCR_FARG(i as u32))?;
                self.jump(APPLET_ADDR)?;
                for _ in 0..4 {
                    let fsr: u8 = self.read_byte(EEFC_FSR)?;
                    if fsr & 0x01 != 0 { break; }
                    if fsr & 0x0E != 0 { Err(FdfuError::FlashWrite(i))? }
                }
                let _ = self.sender.send(Progress::Flashing(i));
            };
            let retries = 4u8;
            for i in 0..retries {
                // Set the GPNVM1 to boot from flash memory.
                self.write_efc_fcr(EFC_SGPB, 0x1)?;
                // Check that the GPNVM1 bit is set.
                self.write_efc_fcr(EFC_GGPB, 0x0)?;
                let byte = self.read_byte(EEFC_FRR)?;
                if byte & (1 << 1) != 0 { break }
                // If the bit is still not set after all retries, return an error
                if i >= retries - 1 { Err(FdfuError::SecurityBit)? }
            }
            Ok(())
        })();
        let _ = match result {
            Ok(_) => self.sender.send(Progress::FlashComplete),
            Err(e) => self.sender.send(Progress::Failed(e)),
        };
    }
fn upload ( & mut self , destination : u32 , data : & [ u8 ] ) { info ! ( " " data len ( ) destination ) ; let result = ( | | { self . enter_update_mode ( ) ? ; self . enter_normal_mode ( ) ? ; // Check the device's security bit self . write_efc_fcr ( EFC_GGPB , 0x0 ) ? ; let word = self . read_word ( EEFC_FRR ) ? ; if word & 0x01 != 0 { Err ( FdfuError :: SecurityBit ) ? } // Write the copy applet into RAM self . copy ( APPLET_ADDR , self . applet ) ? ; let _ = self . sender . send ( Progress :: Applet ) ; // Configure the applet's stack, entry point, destination, and source self . write_word ( APPLET_STACK , IRAM_ADDR + IRAM_SIZE ) ? ; self . write_word ( APPLET_ENTRY , APPLET_ADDR + 0x09 ) ? ; self . write_word ( APPLET_DESTINATION , destination ) ? ; self . write_word ( APPLET_SOURCE , PAGE_BUFFER ( self . applet . len ( ) ) ) ? ; // Send the firmware, page by page let page_size = 512 ; for ( i , page ) in data . chunks ( page_size ) . enumerate ( ) { debug ! ( " " i ) ; self . copy ( PAGE_BUFFER ( self . applet . len ( ) ) , page ) ? ; self . write_word ( APPLET_PAGE , EEFC_FCR_FARG ( i as u32 ) ) ? ; self . jump ( APPLET_ADDR ) ? ; for _ in 0 .. 4 { let fsr : u8 = self . read_byte ( EEFC_FSR ) ? ; if fsr & 0x01 != 0 { break ; } if fsr & 0x0E != 0 { Err ( FdfuError :: FlashWrite ( i ) ) ? } } let _ = self . sender . send ( Progress :: Flashing ( i ) ) ; } ; let retries = 4u8 ; for i in 0 .. retries { // Set the GPNVM1 to boot from flash memory. self . write_efc_fcr ( EFC_SGPB , 0x1 ) ? ; // Check that the GPNVM1 bit is set. self . write_efc_fcr ( EFC_GGPB , 0x0 ) ? ; let byte = self . read_byte ( EEFC_FRR ) ? ; if byte & ( 1 << 1 ) != 0 { break } // If the bit is still not set after all retries, return an error if i >= retries - 1 { Err ( FdfuError :: SecurityBit ) ? } } Ok ( ( ) ) } ) ( ) ; let _ = match result { Ok ( _ ) => self . sender . send ( Progress :: FlashComplete ) , Err ( e ) => self . sender . send ( Progress :: Failed ( e ) ) , } ; }
Uploads the given buffer of data into the given address on the ATSAM.
Uploads the given buffer of data into the given address on the ATSAM .
&mut self
destination
u32
data
&[u8]