#![no_std] use ral_registers as ral; pub type PIT = ral_registers::Instance; #[repr(C)] #[allow(non_snake_case)] pub struct RegisterBlock { pub MCR: u32, reserved_0: [u8; 220], pub LTMR64H: u32, pub LTMR64L: u32, reserved_1: [u8; 24], pub TIMER: [TIMER::RegisterBlock; 4], } ral_registers::register! { #[doc = "PIT Module Control Register"] pub MCR RW [ #[doc = "Freeze"] FRZ start(0) width(1) RW { #[doc = "Timers continue to run in Debug mode."] RUN = 0, #[doc = "Timers are stopped in Debug mode."] STOP = 0x1, } #[doc = "Module Disable for PIT"] MDIS start(1) width(1) RW { #[doc = "Clock for standard PIT timers is enabled."] ENABLE = 0, #[doc = "Clock for standard PIT timers is disabled."] DISABLE = 0x1, } ] } ral_registers::register! { #[doc = "PIT Upper Lifetime Timer Register"] pub LTMR64H RO [] } ral_registers::register! { #[doc = "PIT Lower Lifetime Timer Register"] pub LTMR64L RO [] } #[allow(non_snake_case)] pub mod TIMER { #[allow(non_snake_case)] #[repr(C)] pub struct RegisterBlock { pub LDVAL: u32, pub CVAL: u32, pub TCTRL: u32, pub TFLG: u32, } ral_registers::register! { #[doc = "Timer Load Value Register"] pub LDVAL RW [] } ral_registers::register! { #[doc = "Timer Current Value Register"] pub CVAL RO [] } ral_registers::register! { #[doc = "Timer Control Register"] pub TCTRL RW [ #[doc = "Timer Enable"] TEN start(0) width(1) RW {} #[doc = "Timer Interrupt Enable"] TIE start(1) width(1) RW {} #[doc = "Chain Mode"] CHN start(2) width(1) RW {} ] } ral_registers::register! { #[doc = "Timer Flag Register"] pub TFLG RW [ #[doc = "Timer Interrupt Flag"] TIF start(0) width(1) RW { } ] } } /// Read the lifetime counter value as a `u64`. /// /// This routine assumes that you've chained timers 0 and /// timers 1 together, forming the lifetime timer. It also /// assumes that the timers are enabled. /// /// The implementation includes the recommendation in errata /// ERR050130. pub fn read_lifetime_value(pit: PIT) -> u64 { let mut h = ral::read_reg!(self, pit, LTMR64H); let mut l = ral::read_reg!(self, pit, LTMR64L); // ERR050130 says // // "[...] if the read value of LTMR64L is equal to LDVAL0 [...]" if ral::read_reg!(self, pit, TIMER[0].LDVAL) == l { // "[...] then read both LTMR64H and LTMR64L registers for // one additional time to obtain the correct lifetime value." h = ral::read_reg!(self, pit, LTMR64H); l = ral::read_reg!(self, pit, LTMR64L); } (u64::from(h) << 32) | u64::from(l) }