lpc55-hal 0.5.0

Hardware Abstraction Layer (HAL) for the NXP LPC55S6x ARM Cortex-33 microcontrollers
Documentation
#![no_main]
#![no_std]

extern crate panic_semihosting; // 4004 bytes
                                // extern crate panic_halt; // 672 bytes

use cortex_m_rt::entry;
use cortex_m_semihosting::dbg;
use cortex_m_semihosting::heprintln;

use hal::prelude::*;
use lpc55_hal as hal;

fn autocal(adc: &hal::raw::ADC0) {
    // Calibration + offset trimming
    adc.ofstrim
        .write(|w| unsafe { w.ofstrim_a().bits(10).ofstrim_b().bits(10) });

    // Request calibration
    adc.ctrl.modify(|_, w| w.cal_req().set_bit());

    // wait for auto-cal to be ready.
    while (!adc.gcc[0].read().rdy().bits()) || (!adc.gcc[1].read().rdy().bits()) {}

    let gain_a = adc.gcc[0].read().gain_cal().bits();
    let gain_b = adc.gcc[1].read().gain_cal().bits();

    let gcr_a = (((gain_a as u32) << 16) / (0x1FFFFu32 - gain_a as u32)) as u16;
    let gcr_b = (((gain_b as u32) << 16) / (0x1FFFFu32 - gain_b as u32)) as u16;

    adc.gcr[0].write(|w| unsafe { w.gcalr().bits(gcr_a) });
    adc.gcr[1].write(|w| unsafe { w.gcalr().bits(gcr_b) });

    adc.gcr[0].write(|w| w.rdy().set_bit());
    adc.gcr[1].write(|w| w.rdy().set_bit());

    while !adc.stat.read().cal_rdy().bits() {}
}

#[entry]
fn main() -> ! {
    heprintln!("Hello ADC");

    // Get pointer to all device peripherals.
    let mut hal = hal::new();

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

    // Acquire PUF in an enabled state
    let adc = hal.adc.enabled(&mut hal.pmc, &mut hal.syscon);
    // let adc = hal::Adc::from(dp.ADC0).enabled(&mut syscon);

    let adc = adc.release();

    adc.ctrl
        .write(|w| w.dozen().set_bit().cal_avgs().cal_avgs_7());

    adc.cfg.write(|w| unsafe {
        w.pwren()
            .set_bit()
            .pudly()
            .bits(0x80)
            .refsel()
            .refsel_1()
            .pwrsel()
            .pwrsel_1()
            .tprictrl()
            .bits(0)
    });

    // No pause for now, but could be interesting
    adc.pause.write(|w| unsafe { w.bits(0) });

    // Set 0 for watermark
    adc.fctrl[0].write(|w| unsafe { w.fwmark().bits(0) });
    adc.fctrl[1].write(|w| unsafe { w.fwmark().bits(0) });

    // turn on!
    adc.ctrl.modify(|_, w| w.adcen().set_bit());

    heprintln!("Auto calibrating..");
    autocal(&adc);

    // channel 13 (1V ref), single ended A, high res
    adc.cmdl1
        .write(|w| unsafe { w.adch().bits(13).ctype().ctype_0().mode().mode_1() });

    adc.cmdh1.write(|w| unsafe {
        w.avgs()
            .avgs_5() // average 2^5 samples
            .cmpen()
            .bits(0) // disable compare
            .loop_()
            .bits(0) // no loop
            .next()
            .bits(0) // no next command
    });

    adc.tctrl[0].write(|w| unsafe {
        w.hten()
            .set_bit()
            .fifo_sel_a()
            .fifo_sel_a_0()
            .fifo_sel_b()
            .fifo_sel_b_0()
            .tcmd()
            .bits(1)
    });

    heprintln!("ADC CTRL. {:02X}", adc.ctrl.read().bits());
    heprintln!("ADC  CFG. {:02X}", adc.cfg.read().bits());
    heprintln!("ADC stat: {:02X}", adc.stat.read().bits());

    // SW trigger the trigger event 0
    adc.swtrig.write(|w| unsafe { w.bits(1) });

    dbg!("triggered");

    let count0 = adc.fctrl[0].read().fcount().bits();

    heprintln!("FIFO0 conversions {}", count0);

    let result = adc.resfifo[0].read().bits();
    let valid = result & 0x80000000;
    let sample = (result & 0xffff) as u16;

    if valid != 0 {
        heprintln!("sample = {:02x}", sample);
    } else {
        heprintln!("No result from ADC!");
    }

    for i in 0..10 {
        adc.swtrig.write(|w| unsafe { w.bits(1) });
        while adc.fctrl[0].read().fcount().bits() == 0 {}
        let result = adc.resfifo[0].read().bits();
        assert!((result & 0x80000000) != 0);
        let sample = (result & 0xffff) as u16;
        heprintln!("sample{} = {:02x}", i, sample);
    }

    heprintln!("looping");
    loop {
        heprintln!("looping");
    }
}