pub struct Efc { /* private fields */ }Expand description
Interface to an EFC instance
Partial Programming
- Must be done using 32-bit (or higher) boundaries
- 8 or 16-bit boundaries must be filled with 0xFF (full 32-bits must be written to the buffer)
- See Section 19.4.3.2 https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11158-32-bit%20Cortex-M4-Microcontroller-SAM4N16-SAM4N8_Datasheet.pdf
Example memory.x configuration (atsam4s8b)
MEMORY
{
FLASH (rx) : ORIGIN = 0x00400000, LENGTH = 512K
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
CS0 (xrw) : ORIGIN = 0x60000000, LENGTH = 16M
CS1 (xrw) : ORIGIN = 0x61000000, LENGTH = 16M
CS2 (xrw) : ORIGIN = 0x62000000, LENGTH = 16M
CS3 (xrw) : ORIGIN = 0x63000000, LENGTH = 16M
}
_flash = ORIGIN(FLASH);// 512K flash (unfortunately we need this at compile-time, not link time)
const FLASH_CONFIG_SIZE: usize = 524288 / core::mem::size_of::<u32>();
extern "C" {
#[link_name = "_flash"]
static mut FLASH_CONFIG: [u32; FLASH_CONFIG_SIZE];
}
use hal::efc::Efc;
use atsam4_hal::pac::Peripherals;
let peripherals = Peripherals::take().unwrap();
// Clock configuration will also do a small bit of the EFC init
let _clocks = ClockController::new(
peripherals.PMC,
&peripherals.SUPC,
&peripherals.EFC0,
MainClock::Crystal12Mhz,
SlowClock::RcOscillator32Khz,
);
// Setup efc driver
// FLASH_CONFIG indicates where the usable flash starts
let mut efc = Efc::new(cx.device.EFC0, unsafe { &mut FLASH_CONFIG });
// Retrieve the uid from the efc
let uid = efc.read_unique_id().unwrap();
// Erase user signature
efc.erase_user_signature().unwrap();
// Write to the user signature (max 512 bytes)
efc.write_user_signature(&[1,2,3]).unwrap();
// Read back the user signatfure
let mut sig: [u32; 3];
efc.read_user_signature(&mut sig, sig.len()).unwrap();Implementations§
Source§impl Efc
impl Efc
Sourcepub fn new(efc: EFC, storage: &'static mut [u32]) -> Efc
pub fn new(efc: EFC, storage: &'static mut [u32]) -> Efc
Takes ownership of the peripheral and storage area
Sourcepub fn free(self) -> (EFC, &'static mut [u32])
pub fn free(self) -> (EFC, &'static mut [u32])
Consumes self and returns back the raw peripheral and associated storage
Sourcepub fn lock(&self, start: u32, end: u32) -> Result<(u32, u32), EfcError>
pub fn lock(&self, start: u32, end: u32) -> Result<(u32, u32), EfcError>
Lock all the regions in the given address range. The actual lock range is reported through two output parameters. Returns: (actual_start, actual_end)
Sourcepub fn unlock(&self, start: u32, end: u32) -> Result<(u32, u32), EfcError>
pub fn unlock(&self, start: u32, end: u32) -> Result<(u32, u32), EfcError>
Unlock all the regions in the given address range. The actual unlock range is reported through two output parameters.
Sourcepub fn is_locked(&self, start: u32, end: u32) -> Result<u32, EfcError>
pub fn is_locked(&self, start: u32, end: u32) -> Result<u32, EfcError>
Get the number of locked regions inside the given address range.
Sourcepub fn is_gpnvm_set(&self, gpnvm: u8) -> Result<bool, EfcError>
pub fn is_gpnvm_set(&self, gpnvm: u8) -> Result<bool, EfcError>
Check if the given GPNVM bit is set or not
Sourcepub fn enable_security_bit(&self) -> Result<(), EfcError>
pub fn enable_security_bit(&self) -> Result<(), EfcError>
Set security bit
Sourcepub fn is_security_bit_enabled(&self) -> Result<bool, EfcError>
pub fn is_security_bit_enabled(&self) -> Result<bool, EfcError>
Check if security bit is enabled
Sourcepub fn read_user_signature(
&self,
data: &mut [u32],
len: usize,
) -> Result<(), EfcError>
pub fn read_user_signature( &self, data: &mut [u32], len: usize, ) -> Result<(), EfcError>
Read the flash user signature
Sourcepub fn write_user_signature(&mut self, data: &[u32]) -> Result<(), EfcError>
pub fn write_user_signature(&mut self, data: &[u32]) -> Result<(), EfcError>
Write the flash user signature
Sourcepub fn erase_user_signature(&self) -> Result<(), EfcError>
pub fn erase_user_signature(&self) -> Result<(), EfcError>
Erase the flash user signature
Trait Implementations§
Source§impl NorFlash for Efc
impl NorFlash for Efc
Source§const WRITE_SIZE: usize
const WRITE_SIZE: usize
32-bits is the smallest write size If you’d like to write smaller amounts, you must pad the rest of the 4 bytes with 0xFFs
Source§const ERASE_SIZE: usize
const ERASE_SIZE: usize
NOTE: We can optimize erase quite a bit by trying to combine multiple erase bounds e.g. pages then sectors then pages
The actual erase will vary depending on the situation 4 pages (* 512 -> 2048) - (EPA) Only for 8KB sectors 8 pages (* 512 -> 4096) - (EPA) Can be done anywhere 16 pages (* 512 -> 8192) - (EPA) Can be done anywhere 32 pages (* 512 -> 16384) - (EPA) Not valid for 8KB sectors 1 sector - (ES) Size depends on which sector
- Sector 0 (8192)
- Sector 1 (8192)
- Sector 2 (49152)
- Sector 3+ (65536) See 2.3.1 for more details http://ww1.microchip.com/downloads/en/Appnotes/Atmel-42218-EEPROM-Emulation-Using-Internal-Flash-SAM4_AT4066_AP-Note.pdf All pages - For a flash bank (for chips with dual bank flashes)
If your chip has two banks, you must call erase twice to erase both banks.
Setting the smallest safe interval as the “default”
Source§impl ReadNorFlash for Efc
impl ReadNorFlash for Efc
Source§fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error>
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error>
Reads from atsam4 internal flash
NOTE: EEFC does not have a requirement that reads must start from an aligned address. However we’re imposing this restriction due to: 1. Reads are faster if they are aligned 2. Less complicated logic 3. You shouldn’t really be using this for unaligned reads anyways