diff --git a/examples/zero-tasks.rs b/examples/zero-tasks.rs index bcc3bc31c36b252d3fdda1df389ae2463b5e2b97..9e81802197822cb7ebfdf71de65dfc43a28b023a 100644 --- a/examples/zero-tasks.rs +++ b/examples/zero-tasks.rs @@ -1,5 +1,5 @@ //! Minimal example with zero tasks -#![deny(unsafe_code)] +// #![deny(unsafe_code)] // IMPORTANT always include this feature gate #![feature(proc_macro)] #![no_std] @@ -23,24 +23,114 @@ app! { device: lpc176x5x, } +// pll0 feed sequence. +fn pll0_feed_sequence(syscon: &lpc176x5x::SYSCON) { + syscon + .pll0feed + .write(|w| unsafe { w.pll0feed().bits(0xAA) }); + syscon + .pll0feed + .write(|w| unsafe { w.pll0feed().bits(0x55) }); +} + // The initialization phase. // // This runs first and within a *global* critical section. Nothing can preempt // this function. fn init(p: init::Peripherals) { - use lpc176x5x::syscon::clksrcsel::*; + // use lpc176x5x::syscon::clksrcsel::*; + // use lpc176x5x::syscon::scs::*; + // use lpc176x5x::syscon::clkoutcfg::*; // This function has access to all the peripherals of the device let itm = p.ITM; - iprintln!(&itm.stim[0], "Hello, world!"); - let r = p.SYSCON.clksrcsel.read().clksrc(); - match r { - CLKSRCR::SELECTS_THE_INTERNAL => rtfm::bkpt(), - _ => rtfm::bkpt(), + iprintln!(&itm.stim[0], "1769 init"); + // let r = p.SYSCON.clksrcsel.read().clksrc(); + // match r { + // CLKSRCR::SELECTS_THE_INTERNAL => rtfm::bkpt(), + // _ => rtfm::bkpt(), + // } + + // setup clock output to p1.27 + p.SYSCON + .clkoutcfg + .write(|w| w.clkoutsel().selects_the_cpu_cloc().clkout_en().set_bit()); + + iprintln!( + &itm.stim[0], + "CLKSRSEL {:?}", + p.SYSCON.clksrcsel.read().clksrc() + ); + iprintln!( + &itm.stim[0], + "CLKOUTDIV {:?}", + p.SYSCON.clkoutcfg.read().clkoutdiv().bits() + ); + + // connect (rout) cklout to p1.27 + p.PINCONNECT.pinsel3.write(|w| w.p1_27().clkout()); + // set the pin direction to output + p.GPIO.dir1.write(|w| w.pindir27().set_bit()); + + // enable external oscillator, and spinwait until ready + let mut x = 0; + p.SYSCON.scs.write(|w| w.oscen().enabled()); + while p.SYSCON.scs.read().oscstat().is_not_ready() { + x += 1; + } + + p.SYSCON.cclkcfg.write(|w| unsafe { w.cclksel().bits(3) }); // PLL0 / 4 + + // periheral clock selection is on reset CCLK / 4 + p.SYSCON + .clksrcsel + .write(|w| w.clksrc().selects_the_main_osc()); + // at this point the output clock would be 12Mhz/4 + + // multiplier value 14..0 (stored is N - 1) + // pre divider value 16..23 (stored is N - 1) + // 0x0005 0063 + // N = 6 + // M = 100 + // + // main oscillator at 400 Mhz (275-550) + // M = (400 * 6) / (2 * 12) + + p.SYSCON.pll0cfg.write(|w| unsafe { + w.msel0().bits(100 - 1).nsel0().bits(6 - 1) + }); + + pll0_feed_sequence(&p.SYSCON); + + // enable pll0 + p.SYSCON.pll0con.write(|w| w.plle0().set_bit()); + + pll0_feed_sequence(&p.SYSCON); + + // wait until PLL0 locked + x = 0; + while p.SYSCON.pll0stat.read().plock0().bit_is_clear() { + x += 1; } - //iprintln!(&itm.stim[0], "{:?}", p.SYSCON.clksrcsel.read()); + // enable and connect PLL0 + p.SYSCON + .pll0con + .write(|w| w.plle0().set_bit().pllc0().set_bit()); - // .. + pll0_feed_sequence(&p.SYSCON); + + // wait until PLL0 both connected and enabled + x = 0; + while p.SYSCON.pll0stat.read().plle0_stat().bit_is_clear() + || p.SYSCON.pll0stat.read().pllc0_stat().bit_is_clear() + { + x += 1; + } + + iprintln!(&itm.stim[0], "-- here -- {}", x); + + rtfm::bkpt(); + // setup ethernet mac } // The idle loop.