panic_handler.rs 3.62 KiB
#![feature(panic_info_message)]
#![no_main]
#![no_std]
extern crate lpc4370_drivers;
use rtfm::app;
// CCU driver
use lpc4370::ccu1::clk_m4_bus_cfg;
use lpc4370_drivers::ccu_config;
// UART driver
use lpc4370::usart0::{
    iir::INTIDR,
    lcr::{BCW, DLABW, PEW, PSW, SBSW, WLSW},
use lpc4370_drivers::{
    serial::{Read, Serial, Write as SerialWrite},
    timer::{InterruptType, Timer},
static TIMER_PERIOD: u32 = 8192;
// Panic handler for USART3
use lpc4370_drivers::{uart_panic_handler, debug::PanicInfo};
uart_panic_handler!(lpc4370::USART3);
#[app(device = lpc4370)]
const APP: () = {
    static mut TIMER: Timer<lpc4370::TIMER0> = ();
    #[init]
    fn init() -> init::LateResources {
        let mut serial = Serial::<lpc4370::USART3>::new(device.USART3, 0x41, 0x0, 0x0, None);
        serial.lcr(
            WLSW::_8_BIT_CHARACTER_LENGTH,
            SBSW::_1_STOP_BIT,
            PEW::DISABLE_PARITY_GENERERATION,
            PSW::ODD_PARITY,
            BCW::DISABLED,
            DLABW::DISABLED,
        serial.ier(true, false, false, false, false);
        // Configure timer
        let timer = Timer::<lpc4370::TIMER0>::new(device.TIMER0);
        timer.start_timer(false);
        timer.set_match(0, TIMER_PERIOD);
        timer.set_prescaler(1024, Some(0));
        timer.mr0(true, true, false);
        timer.start_timer(true);
        // USART3 I/O
        unsafe {
            device.SCU.sfsp90_[3].write(|w| w.mode().bits(0x7).epun().bit(true)); // TX
            device.SCU.sfsp90_[4].write(|w| w.mode().bits(0x7).epun().bit(true).ezi().bit(true)); // RX
        // Configure PLL1 for use with UART3
        unsafe {
            // Select the IRC as BASE_M4_CLK source
            device.CGU.base_m4_clk.write(|w| w.clk_sel().bits(0x1));
            // Enable the crystal oscillator
            device.CGU.xtal_osc_ctrl.modify(|_, w| w.hf().bit(false));
            device.CGU.xtal_osc_ctrl.modify(|_, w| w.enable().bit(false));
            // Wait 250us
            for i in 0 .. 3_000 {
                core::ptr::read_volatile(&i);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
} device.CGU.pll1_ctrl.write(|w| w .pd().bit(false) .clk_sel().bits(0x6) // Select the crystal oscillator as clock source .msel().bits(20) .nsel().bits(1) // Select the M and N divider values .psel().bits(0) .fbsel().bit(true) .bypass().bit(false) .direct().bit(false)); // Wait for the PLL to lock while !device.CGU.pll1_stat.read().lock().bit() {} // Set PLL1 p-divider to divide by 2 (DIRECT=0; PSEL=0) device.CGU.pll1_ctrl.modify(|_, w| w.direct().bit(false).psel().bits(0x0)); // Select PLL1 as base_m4_clk source device.CGU.base_m4_clk.modify(|_, w| w.clk_sel().bits(0x09)); // Wait for 50us for i in 0 .. 600 { core::ptr::read_volatile(&i); } // Enable direct output mode device.CGU.pll1_ctrl.modify(|_, w| w.direct().bit(true)); // Enable clock on UART3 device.CGU.base_uart3_clk.write(|w| w.clk_sel().bits(0x09)); // configure crystal oscillator } unsafe { PANIC_UART = Some(serial); } init::LateResources { TIMER: timer, } } #[idle] fn idle() -> ! { loop {} } #[interrupt(resources = [TIMER])] fn TIMER0() { panic!("this is being printed over UART"); resources .TIMER .clear_interrupt(InterruptType::MatchChannel, 0); } };