Skip to main content

Efc

Struct Efc 

Source
pub struct Efc { /* private fields */ }
Expand description

Interface to an EFC instance

Partial Programming

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

Source

pub fn new(efc: EFC, storage: &'static mut [u32]) -> Efc

Takes ownership of the peripheral and storage area

Source

pub fn free(self) -> (EFC, &'static mut [u32])

Consumes self and returns back the raw peripheral and associated storage

Source

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)

Source

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.

Source

pub fn is_locked(&self, start: u32, end: u32) -> Result<u32, EfcError>

Get the number of locked regions inside the given address range.

Source

pub fn set_gpnvm(&self, gpnvm: u8) -> Result<(), EfcError>

Set the given GPNVM bit

Source

pub fn clear_gpnvm(&self, gpnvm: u8) -> Result<(), EfcError>

Clear the given GPNVM bit

Source

pub fn is_gpnvm_set(&self, gpnvm: u8) -> Result<bool, EfcError>

Check if the given GPNVM bit is set or not

Source

pub fn enable_security_bit(&self) -> Result<(), EfcError>

Set security bit

Source

pub fn is_security_bit_enabled(&self) -> Result<bool, EfcError>

Check if security bit is enabled

Source

pub fn read_unique_id(&self) -> Result<[u32; 4], EfcError>

Read the flash unique ID

Source

pub fn read_user_signature( &self, data: &mut [u32], len: usize, ) -> Result<(), EfcError>

Read the flash user signature

Source

pub fn write_user_signature(&mut self, data: &[u32]) -> Result<(), EfcError>

Write the flash user signature

Source

pub fn erase_user_signature(&self) -> Result<(), EfcError>

Erase the flash user signature

Trait Implementations§

Source§

impl ErrorType for Efc

Source§

type Error = EfcError

Errors returned by this NOR flash.
Source§

impl NorFlash for Efc

Source§

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

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

If your chip has two banks, you must call erase twice to erase both banks.

Setting the smallest safe interval as the “default”

Source§

fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error>

Erases range of addresses Will not succeed if the erase bounds are not set to an allowed boundary.

  • page
  • sector
  • bank
Source§

fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error>

Write a data buffer on flash.

This function works in polling mode, and thus only returns when the data has been effectively written.

Source§

impl ReadNorFlash for Efc

Source§

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

Source§

const READ_SIZE: usize

The minumum number of bytes the storage peripheral can read
Source§

fn capacity(&self) -> usize

The capacity of the peripheral in bytes.

Auto Trait Implementations§

§

impl !Sync for Efc

§

impl !UnwindSafe for Efc

§

impl Freeze for Efc

§

impl RefUnwindSafe for Efc

§

impl Send for Efc

§

impl Unpin for Efc

§

impl UnsafeUnpin for Efc

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.