use super::ds::*;
use std::mem;
use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT};
use std::time::Duration;
use wpilib_sys::*;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum RobotBaseInitError {
HalInitFailed,
AlreadyInit,
}
static ROBOT_INITED: AtomicBool = ATOMIC_BOOL_INIT;
#[derive(Debug)]
pub struct RobotBase {}
impl RobotBase {
#[allow(clippy::new_ret_no_self)]
pub fn new() -> Result<RobotBase, RobotBaseInitError> {
if ROBOT_INITED.compare_and_swap(false, true, Ordering::AcqRel) {
return Err(RobotBaseInitError::AlreadyInit);
}
if unsafe { HAL_Initialize(500, 0) } == 0 {
return Err(RobotBaseInitError::HalInitFailed);
}
report_usage(usage::resource_types::Language, unsafe {
mem::transmute(*b"Rust")
});
println!("\n********** Hardware Init **********\n");
Ok(RobotBase {})
}
pub fn start_competition() {
unsafe {
HAL_ObserveUserProgramStarting();
}
println!("\n********** Robot program starting **********\n");
}
pub fn make_ds(&self) -> DriverStation {
DriverStation::from_base(self).expect("HAL FAILED ON DS CREATION")
}
#[inline(always)]
pub fn fpga_version() -> HalResult<i32> {
hal_call!(HAL_GetFPGAVersion())
}
#[inline(always)]
pub fn fpga_revision() -> HalResult<i64> {
hal_call!(HAL_GetFPGARevision())
}
#[inline(always)]
pub fn fpga_time() -> HalResult<u64> {
hal_call!(HAL_GetFPGATime())
}
pub fn fpga_time_duration() -> HalResult<Duration> {
let usec = Self::fpga_time()?;
let sec: u64 = usec / 1_000_000;
let nsec: u32 = (usec % 1_000_000) as u32 * 1000;
Ok(Duration::new(sec, nsec))
}
#[inline(always)]
pub fn user_button() -> HalResult<bool> {
Ok(hal_call!(HAL_GetFPGAButton())? != 0)
}
pub fn is_browned_out() -> HalResult<bool> {
Ok(hal_call!(HAL_GetBrownedOut())? != 0)
}
pub fn is_system_active() -> HalResult<bool> {
Ok(hal_call!(HAL_GetSystemActive())? != 0)
}
pub fn battery_voltage() -> HalResult<f64> {
hal_call!(HAL_GetVinVoltage())
}
}
impl Drop for RobotBase {
fn drop(&mut self) {
unsafe {
HAL_ReleaseDSMutex();
}
}
}