#[derive(Debug, Eq, PartialEq)]
pub struct Clock {
count: u64,
period: u64,
}
impl Clock {
pub fn new(period: u64) -> Clock {
Clock {
count: 0,
period: period,
}
}
pub fn tick(&mut self) -> bool {
self.count += 1;
assert!(self.count <= self.period);
if self.count >= self.period {
self.count = 0;
true
} else {
false
}
}
pub fn reset(&mut self) {
self.count = 0;
}
pub fn count(&self) -> u64 {
self.count
}
pub fn period(&self) -> u64 {
self.period
}
}
#[test]
fn test_clock() {
let mut c = Clock::new(3);
assert_eq!(c.period(), 3);
assert_eq!(c.count(), 0);
assert!(!c.tick());
assert_eq!(c.count(), 1);
assert!(!c.tick());
assert_eq!(c.count(), 2);
assert!(c.tick());
assert_eq!(c.count(), 0);
assert!(!c.tick());
assert!(!c.tick());
assert!(c.tick());
assert!(!c.tick());
c.reset();
assert!(!c.tick());
assert!(!c.tick());
assert!(c.tick());
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub struct Timer {
period: u64,
next_start: u64,
next_stop: u64,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum TimerEvent {
RisingEdge,
FallingEdge,
}
impl Timer {
pub fn new(period: u64, offset: u64, duration: u64) -> Timer {
assert!(offset < period);
assert!(duration < period);
Timer {
period,
next_start: offset,
next_stop: offset + duration,
}
}
pub fn next_start_time(&self) -> u64 {
self.next_start
}
pub fn next_stop_time(&self) -> u64 {
self.next_stop
}
pub fn next_event_time(&self) -> u64 {
if self.next_start < self.next_stop {
self.next_start
} else {
self.next_stop
}
}
pub fn update(&mut self, time: u64) -> Option<TimerEvent> {
if self.next_start <= self.next_stop && self.next_start <= time {
if self.next_stop == self.next_start {
self.next_stop += self.period;
}
self.next_start += self.period;
Some(TimerEvent::RisingEdge)
} else if self.next_stop <= time {
self.next_stop += self.period;
Some(TimerEvent::FallingEdge)
} else {
None
}
}
pub fn is_active(&self) -> bool {
self.next_start > self.next_stop
}
}
pub fn next_timer_event(timers: &[Timer]) -> u64 {
timers
.iter()
.map(|t| t.next_event_time())
.min()
.unwrap_or(0)
}
#[test]
fn test_timer() {
let mut timer = Timer::new(100, 13, 20);
assert_eq!(timer.next_start_time(), 13);
assert_eq!(timer.next_stop_time(), 13 + 20);
assert_eq!(timer.update(12), None);
assert_eq!(timer.next_start_time(), 13);
assert_eq!(timer.next_stop_time(), 13 + 20);
assert_eq!(timer.update(13), Some(TimerEvent::RisingEdge));
assert_eq!(timer.next_start_time(), 13 + 100);
assert_eq!(timer.next_stop_time(), 13 + 20);
assert_eq!(timer.update(13 + 20 + 5), Some(TimerEvent::FallingEdge));
assert_eq!(timer.next_start_time(), 13 + 100);
assert_eq!(timer.next_stop_time(), 13 + 20 + 100);
let mut v = vec![];
while let Some(e) = timer.update(300) {
v.push(e);
}
assert_eq!(
v,
vec![
TimerEvent::RisingEdge,
TimerEvent::FallingEdge,
TimerEvent::RisingEdge,
TimerEvent::FallingEdge,
]
);
}
#[test]
fn test_timer_zero_duration() {
let mut timer = Timer::new(100, 13, 0);
assert_eq!(timer.next_start_time(), 13);
assert_eq!(timer.update(12), None);
assert_eq!(timer.next_start_time(), 13);
assert_eq!(timer.update(13), Some(TimerEvent::RisingEdge));
assert_eq!(timer.next_start_time(), 13 + 100);
assert_eq!(timer.update(13 + 100), Some(TimerEvent::RisingEdge));
}
#[test]
fn test_next_timer_event() {
let t1 = Timer::new(100, 13, 0);
let t2 = Timer::new(100, 14, 0);
assert_eq!(next_timer_event(&[t1, t2]), 13);
}