Created
June 26, 2019 18:56
-
-
Save almindor/79a627cd23e766d2b5c7c6696afe4e03 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
/* | |
* Basic blinking LEDs example using pmu sleep | |
* for "sleep" in a loop. Blinks each led once and goes to the next one. | |
*/ | |
extern crate panic_halt; | |
use riscv_rt::entry; | |
use hifive1::hal::prelude::*; | |
use hifive1::hal::e310x::Peripherals; | |
use hifive1::sprintln; | |
const PMU_KEY_VAL: u32 = 0x51F15E; | |
const SLEEP_PROGRAM: [u32; 8] = [ | |
0x2F0, // assert corerst | |
0x3F0, // assert hfclkrst | |
0x3D0, // deassert pmu_out_1 | |
0x3C0, // deassert pmu_out_0 | |
0x3C0, // repeats | |
0x3C0, | |
0x3C0, | |
0x3C0, | |
]; | |
const WAKE_PROGRAM: [u32; 8] = [ | |
0x3F0, // assert all resets and enable all power supplies | |
0x2F8, // idle 2^8 cycles, then deassert hfclkrst | |
0x030, // deassert corerst and padrst | |
0x030, // repeats | |
0x030, | |
0x030, | |
0x030, | |
0x030, | |
]; | |
#[entry] | |
fn main() -> ! { | |
let p = Peripherals::take().unwrap(); | |
let gpio = p.GPIO0.split(); | |
// Configure clocks | |
let clocks = hifive1::clock::configure(p.PRCI, p.AONCLK, 320.mhz().into()); | |
// Configure UART for stdout | |
hifive1::stdout::configure(p.UART0, gpio.pin17, gpio.pin16, 115_200.bps(), clocks); | |
// set correct sleep and wake programs | |
unsafe { | |
for i in 0..7 { | |
p.PMU.pmukey.write(|w| w.bits(PMU_KEY_VAL)); | |
p.PMU.pmusleeppm[i].write(|w| w.bits(SLEEP_PROGRAM[i])); | |
// sprintln!("Set sleep p[{}] = 0x{:X}", i, SLEEP_PROGRAM[i]); | |
p.PMU.pmukey.write(|w| w.bits(PMU_KEY_VAL)); | |
p.PMU.pmuwakepm[i].write(|w| w.bits(WAKE_PROGRAM[i])); | |
// sprintln!("Set wake p[{}] = 0x{:X}", i, WAKE_PROGRAM[i]); | |
} | |
} | |
// let mut i = 0; | |
// for sr in &p.PMU.pmusleeppm { | |
// sprintln!("Sleep instr{} = 0x{:X}", i, sr.read().bits()); | |
// i = i + 1; | |
// } | |
// i = 0; | |
// for wr in &p.PMU.pmuwakepm { | |
// sprintln!("Wake instr{} = 0x{:X}", i, wr.read().bits()); | |
// i = i + 1; | |
// } | |
sprintln!("Going to sleep"); | |
unsafe { | |
// set interrupt source to RTC enabled, each pmu register needs key set before write | |
p.PMU.pmukey.write(|w| w.bits(PMU_KEY_VAL)); | |
p.PMU.pmuie.write(|w| w.rtc().set_bit()); | |
// set RTC clock scale to once per second for easy calculation | |
p.RTC.rtccfg.write(|w| w.scale().bits(15)); | |
// get current RTC clock value scaled | |
let rtc_now = p.RTC.rtcs.read().bits(); | |
// set RTC clock comparator | |
p.RTC.rtccmp.write(|w| w.bits(rtc_now + 15)); // 15 second delay on sleep | |
// go to sleep for 15s, need to set pmukey here as well | |
p.PMU.pmukey.write(|w| w.bits(PMU_KEY_VAL)); | |
p.PMU.pmusleep.write(|w| w.bits(0xFFFF)); | |
} | |
sprintln!("EOL"); | |
loop {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment