lpc55-hal 0.5.0

Hardware Abstraction Layer (HAL) for the NXP LPC55S6x ARM Cortex-33 microcontrollers
Documentation
#![no_main]
#![no_std]
/// Simple example to measure the core clock frequency
extern crate panic_semihosting; // 4004 bytes
                                // extern crate panic_halt; // 672 bytes

use cortex_m_rt::entry;
use cortex_m_semihosting::{heprint, heprintln};

use hal::{
    peripherals::pfr::{Cfpa, KeyType},
    prelude::*,
};
use lpc55_hal as hal;

macro_rules! dump_hex {
    ($array:expr, $length:expr ) => {
        heprint!("{:?} = ", stringify!($array));
        for i in 0..$length {
            heprint!("{:02X}", $array[i]);
        }
        heprintln!("");
    };
}

#[allow(dead_code)]
fn boot_to_bootrom() -> ! {
    // Best way to boot into MCUBOOT is to erase the first flash page before rebooting.
    use hal::traits::flash::WriteErase;
    let flash = unsafe { hal::peripherals::flash::Flash::steal() }
        .enabled(&mut unsafe { hal::peripherals::syscon::Syscon::steal() });
    hal::drivers::flash::FlashGordon::new(flash)
        .erase_page(0)
        .ok();
    hal::raw::SCB::sys_reset()
}

fn dump_cfpa(cfpa: &Cfpa) {
    heprintln!("header = {:08X}", cfpa.header);
    heprintln!("version = {:08X}", cfpa.version);
    heprintln!("secureVersion = {:08X}", cfpa.secure_fw_version);
    heprintln!("notSecureVersion = {:08X}", cfpa.ns_fw_version);

    heprintln!("imageKeyRevoke = {:08X}", cfpa.image_key_revoke);
    heprintln!("rotkhRevoke = {:08X}", cfpa.rotkh_revoke);
    dump_hex!(cfpa.customer_data, 10);
}

#[entry]
fn main() -> ! {
    let hal = hal::new();

    let mut anactrl = hal.anactrl;
    let mut pmc = hal.pmc;
    let mut syscon = hal.syscon;

    let clocks = hal::ClockRequirements::default()
        .system_frequency(96.MHz())
        .configure(&mut anactrl, &mut pmc, &mut syscon)
        .unwrap();

    dump_hex!(hal::uuid(), 16);
    heprintln!("chip revision: {}", hal::chip_revision());
    let mut pfr = hal.pfr.enabled(&clocks).unwrap();
    let mut cfpa = pfr.read_latest_cfpa().unwrap();
    heprintln!("CFPA:");
    dump_cfpa(&cfpa);

    heprintln!("Increment the version and write back cfpa!");
    cfpa.version += 1;
    cfpa.secure_fw_version += 1;
    cfpa.ns_fw_version += 1;
    // increment a byte of customer data (with overflow)
    cfpa.customer_data[0] = ((1 + (cfpa.customer_data[0] as u16)) & 0xff) as u8;
    pfr.write_cfpa(&cfpa).unwrap();

    heprintln!("Rerun this program and check that Version, firmware versions, and custom data byte all increment.");

    let cmpa = pfr.read_cmpa().unwrap();
    heprintln!("\r\nCMPA:");
    heprintln!("boot_cfg = {:08X}", cmpa.boot_cfg);
    heprintln!("usb.vid = {:08X}", cmpa.usb_vid);
    heprintln!("usb.pid = {:08X}", cmpa.usb_pid);
    heprintln!("secure_boot_cfg = {:08X}", cmpa.secure_boot_cfg);
    dump_hex!(cmpa.rotkh, cmpa.rotkh.len());
    dump_hex!(cfpa.customer_data, 10);
    dump_hex!(cmpa.customer_data, cmpa.customer_data.len());

    heprintln!("\r\nKeyStore:");
    let key_code = pfr.read_key_code(KeyType::User).unwrap();
    dump_hex!(key_code, key_code.len());

    let activation_code = pfr.read_activation_code().unwrap();
    dump_hex!(activation_code, activation_code.len());

    pfr.lock_all().unwrap();

    heprintln!("done.  Must reboot to see CFPA changes take effect.");

    loop {
        // done, insert NOP to avoid optimization weirdness
        continue;
    }
}