Skip to content

Commit

Permalink
Merge pull request #33 from dtwood/add-RTC-from-HIB
Browse files Browse the repository at this point in the history
Add support for RTC from the HIB peripheral
  • Loading branch information
thejpster authored Jul 24, 2020
2 parents 7255859 + 77f4308 commit be36ae7
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 0 deletions.
72 changes: 72 additions & 0 deletions tm4c123x-hal/src/hib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//! A wrapper for the HIB (Hibernation) peripheral
use crate::sysctl;

/// Which source to use for the HIB clock
pub enum Source {
/// HIB clock is from an external oscillator
ExternalOscillator,
/// HIB clock is from the internal low-frequency oscillator
LowFrequencyInternalOscillator,
}

/// A wrapper around the HIB (Hibernation) peripheral
pub struct Hib {
hib: tm4c123x::HIB,
}

impl Hib {
/// Initialize the HIB peripheral, using a clock from `source`
pub fn hib(hib: tm4c123x::HIB, source: Source, _pc: &sysctl::PowerControl) -> Self {
hib.ctl.write(|w| {
match source {
Source::ExternalOscillator => w.oscbyp().set_bit(),
Source::LowFrequencyInternalOscillator => w.oscbyp().clear_bit(),
};

w.clk32en().set_bit();

w
});

while hib.ctl.read().wrc().bit_is_clear() {}
hib.ctl.write(|w| {
match source {
Source::ExternalOscillator => w.oscbyp().set_bit(),
Source::LowFrequencyInternalOscillator => w.oscbyp().clear_bit(),
};

w.oscdrv().set_bit();
w.clk32en().set_bit();
w.rtcen().set_bit();

w
});
while hib.ctl.read().wrc().bit_is_clear() {}

Hib { hib }
}

/// Get the current time, in units of (seconds, subseconds), where a
/// subsecond is 1/32768 seconds
pub fn get_time(&self) -> (u32, u16) {
loop {
let seconds = self.hib.rtcc.read().bits();
let subsec = self.hib.rtcss.read().rtcssc().bits();

if seconds == self.hib.rtcc.read().bits() {
return (seconds, subsec);
}
}
}

/// Get the current time in milliseconds
pub fn get_millis(&self) -> u64 {
let (seconds, subsec) = self.get_time();
let seconds: u64 = seconds.into();
let subsec: u64 = subsec.into();

let millis: u64 = subsec * 1000 / 32_768;
return seconds * 1000 + millis;
}
}
1 change: 1 addition & 0 deletions tm4c123x-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub use crate::tm4c123x::interrupt;
use embedded_hal as hal;

pub mod gpio;
pub mod hib;
pub mod i2c;
pub mod prelude;
pub mod pwm;
Expand Down
76 changes: 76 additions & 0 deletions tm4c129x-hal/src/hib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//! A wrapper for the HIB (Hibernation) peripheral
use crate::sysctl;

/// Which source to use for the HIB clock
pub enum Source {
/// HIB clock is from an external crystal
ExternalCrystal,
/// HIB clock is from an external oscillator
ExternalOscillator,
/// HIB clock is from the internal low-frequency oscillator
LowFrequencyInternalOscillator,
}

/// A wrapper around the HIB (Hibernation) peripheral
pub struct Hib {
hib: tm4c129x::HIB,
}

impl Hib {
/// Initialize the HIB peripheral, using a clock from `source`
pub fn hib(hib: tm4c129x::HIB, source: Source, _pc: &sysctl::PowerControl) -> Self {
hib.ctl.write(|w| {
match source {
Source::ExternalCrystal => w.oscsel().clear_bit().oscbyp().clear_bit(),
Source::ExternalOscillator => w.oscsel().clear_bit().oscbyp().set_bit(),
Source::LowFrequencyInternalOscillator => w.oscsel().set_bit().oscbyp().clear_bit(),
};

w.clk32en().set_bit();

w
});

while hib.ctl.read().wrc().bit_is_clear() {}
hib.ctl.write(|w| {
match source {
Source::ExternalCrystal => w.oscsel().clear_bit().oscbyp().clear_bit(),
Source::ExternalOscillator => w.oscsel().clear_bit().oscbyp().set_bit(),
Source::LowFrequencyInternalOscillator => w.oscsel().set_bit().oscbyp().clear_bit(),
};

w.oscdrv().set_bit();
w.clk32en().set_bit();
w.rtcen().set_bit();

w
});
while hib.ctl.read().wrc().bit_is_clear() {}

Hib { hib }
}

/// Get the current time, in units of (seconds, subseconds), where a
/// subsecond is 1/32768 seconds
pub fn get_time(&self) -> (u32, u16) {
loop {
let seconds = self.hib.rtcc.read().bits();
let subsec = self.hib.rtcss.read().rtcssc().bits();

if seconds == self.hib.rtcc.read().bits() {
return (seconds, subsec);
}
}
}

/// Get the current time in milliseconds
pub fn get_millis(&self) -> u64 {
let (seconds, subsec) = self.get_time();
let seconds: u64 = seconds.into();
let subsec: u64 = subsec.into();

let millis: u64 = subsec * 1000 / 32_768;
return seconds * 1000 + millis;
}
}
1 change: 1 addition & 0 deletions tm4c129x-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub use tm4c_hal::{bb, delay, time};
pub use crate::tm4c129x::interrupt;

pub mod gpio;
pub mod hib;
pub mod i2c;
pub mod prelude;
pub mod serial;
Expand Down

0 comments on commit be36ae7

Please sign in to comment.