1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use crate::base::*;
use crate::task::*;
use crate::shim::*;
use crate::units::*;

/// Delay the current task by the given duration, minus the
/// time that was spent processing the last wakeup loop.
pub struct TaskDelay {
    last_wake_time: FreeRtosTickType,
}

impl TaskDelay {
    /// Create a new helper, marking the current time as the start of the
    /// next measurement.
    pub fn new() -> TaskDelay {
        TaskDelay { last_wake_time: FreeRtosUtils::get_tick_count() }
    }

    /// Delay the execution of the current task by the given duration,
    /// minus the time spent in this task since the last delay.
    pub fn delay_until<D: DurationTicks>(&mut self, delay: D) {
        unsafe {
            freertos_rs_vTaskDelayUntil(&mut self.last_wake_time as *mut FreeRtosTickType,
                                        delay.to_ticks());
        }
    }
}

/// Periodic delay timer.
///
/// Use inside a polling loop, for example: the loop polls this instance every second.
/// The method `should_run` will return true once 30 seconds or more has elapsed
/// and it will then reset the timer for that period.
pub struct TaskDelayPeriodic {
    last_wake_time: FreeRtosTickType,
    period_ticks: FreeRtosTickType,
}

impl TaskDelayPeriodic {
    /// Create a new timer with the set period.
    pub fn new<D: DurationTicks>(period: D) -> TaskDelayPeriodic {
        let l = FreeRtosUtils::get_tick_count();

        TaskDelayPeriodic {
            last_wake_time: l,
            period_ticks: period.to_ticks(),
        }
    }

    /// Has the set period passed? If it has, resets the internal timer.
    pub fn should_run(&mut self) -> bool {
        let c = FreeRtosUtils::get_tick_count();
        if (c - self.last_wake_time) < (self.period_ticks) {
            false
        } else {
            self.last_wake_time = c;
            true
        }
    }

    /// Set a new delay period
    pub fn set_period<D: DurationTicks>(&mut self, period: D) {
        self.period_ticks = period.to_ticks();
    }

    /// Reset the internal timer to zero.
    pub fn reset(&mut self) {
        self.last_wake_time = FreeRtosUtils::get_tick_count();
    }
}