use core::ffi::c_void;
use crate::kernel::timers::{
pvTimerGetTimerID, vTimerSetTimerID, xTimerChangePeriod, xTimerCreateStatic,
xTimerGetExpiryTime, xTimerGetPeriod, xTimerGetTimerDaemonTaskHandle, xTimerIsTimerActive,
xTimerReset, xTimerStart, xTimerStop, StaticTimer_t, TimerCallbackFunction_t,
};
#[cfg(any(feature = "alloc", feature = "heap-4", feature = "heap-5"))]
use crate::kernel::timers::xTimerCreate;
use crate::types::*;
pub struct Timer {
handle: TimerHandle_t,
}
unsafe impl Sync for Timer {}
unsafe impl Send for Timer {}
impl Timer {
#[cfg(all(feature = "timers", any(feature = "alloc", feature = "heap-4", feature = "heap-5")))]
pub fn new_periodic(
name: &[u8],
period_ticks: TickType_t,
callback: TimerCallbackFunction_t,
) -> Option<Self> {
Self::new_internal(name, period_ticks, true, callback)
}
#[cfg(all(feature = "timers", any(feature = "alloc", feature = "heap-4", feature = "heap-5")))]
pub fn new_oneshot(
name: &[u8],
period_ticks: TickType_t,
callback: TimerCallbackFunction_t,
) -> Option<Self> {
Self::new_internal(name, period_ticks, false, callback)
}
#[cfg(all(feature = "timers", any(feature = "alloc", feature = "heap-4", feature = "heap-5")))]
fn new_internal(
name: &[u8],
period_ticks: TickType_t,
auto_reload: bool,
callback: TimerCallbackFunction_t,
) -> Option<Self> {
let handle = xTimerCreate(
name.as_ptr(),
period_ticks,
if auto_reload { pdTRUE } else { pdFALSE },
core::ptr::null_mut(), callback,
);
if handle.is_null() {
None
} else {
Some(Self { handle })
}
}
#[cfg(feature = "timers")]
pub fn new_periodic_static(
name: &[u8],
period_ticks: TickType_t,
callback: TimerCallbackFunction_t,
timer_buffer: &'static mut StaticTimer_t,
) -> Option<Self> {
Self::new_static_internal(name, period_ticks, true, callback, timer_buffer)
}
#[cfg(feature = "timers")]
pub fn new_oneshot_static(
name: &[u8],
period_ticks: TickType_t,
callback: TimerCallbackFunction_t,
timer_buffer: &'static mut StaticTimer_t,
) -> Option<Self> {
Self::new_static_internal(name, period_ticks, false, callback, timer_buffer)
}
#[cfg(feature = "timers")]
fn new_static_internal(
name: &[u8],
period_ticks: TickType_t,
auto_reload: bool,
callback: TimerCallbackFunction_t,
timer_buffer: &'static mut StaticTimer_t,
) -> Option<Self> {
let handle = xTimerCreateStatic(
name.as_ptr(),
period_ticks,
if auto_reload { pdTRUE } else { pdFALSE },
core::ptr::null_mut(),
callback,
timer_buffer as *mut StaticTimer_t,
);
if handle.is_null() {
None
} else {
Some(Self { handle })
}
}
#[cfg(feature = "timers")]
pub fn start(&self) -> bool {
xTimerStart(self.handle, 0) == pdPASS
}
#[cfg(feature = "timers")]
pub fn start_timeout(&self, ticks: TickType_t) -> bool {
xTimerStart(self.handle, ticks) == pdPASS
}
#[cfg(feature = "timers")]
pub fn stop(&self) -> bool {
xTimerStop(self.handle, 0) == pdPASS
}
#[cfg(feature = "timers")]
pub fn stop_timeout(&self, ticks: TickType_t) -> bool {
xTimerStop(self.handle, ticks) == pdPASS
}
#[cfg(feature = "timers")]
pub fn reset(&self) -> bool {
xTimerReset(self.handle, 0) == pdPASS
}
#[cfg(feature = "timers")]
pub fn reset_timeout(&self, ticks: TickType_t) -> bool {
xTimerReset(self.handle, ticks) == pdPASS
}
#[cfg(feature = "timers")]
pub fn set_period(&self, new_period_ticks: TickType_t) -> bool {
xTimerChangePeriod(self.handle, new_period_ticks, 0) == pdPASS
}
#[cfg(feature = "timers")]
pub fn set_period_timeout(&self, new_period_ticks: TickType_t, ticks: TickType_t) -> bool {
xTimerChangePeriod(self.handle, new_period_ticks, ticks) == pdPASS
}
#[cfg(feature = "timers")]
pub fn is_active(&self) -> bool {
xTimerIsTimerActive(self.handle) != pdFALSE
}
#[cfg(feature = "timers")]
pub fn period(&self) -> TickType_t {
xTimerGetPeriod(self.handle)
}
#[cfg(feature = "timers")]
pub fn expiry_time(&self) -> TickType_t {
xTimerGetExpiryTime(self.handle)
}
#[cfg(feature = "timers")]
pub fn set_id<T>(&self, id: *mut T) {
vTimerSetTimerID(self.handle, id as *mut c_void);
}
#[cfg(feature = "timers")]
pub fn get_id<T>(&self) -> Option<*mut T> {
let id = pvTimerGetTimerID(self.handle);
if id.is_null() {
None
} else {
Some(id as *mut T)
}
}
#[cfg(feature = "timers")]
pub fn get_id_raw(&self) -> *mut c_void {
pvTimerGetTimerID(self.handle)
}
pub unsafe fn raw_handle(&self) -> TimerHandle_t {
self.handle
}
pub unsafe fn from_raw(handle: TimerHandle_t) -> Self {
Self { handle }
}
#[cfg(feature = "timers")]
pub fn daemon_task_handle() -> TaskHandle_t {
xTimerGetTimerDaemonTaskHandle()
}
}