use super::sensor_util;
use wpilib_sys::usage::{instances, resource_types};
use wpilib_sys::*;
#[allow(dead_code)]
#[derive(Debug)]
pub struct DigitalOutput {
channel: i32,
handle: HAL_DigitalHandle,
pwm: Option<HAL_DigitalPWMHandle>,
}
impl DigitalOutput {
#[allow(clippy::new_ret_no_self)]
pub fn new(channel: i32) -> HalResult<Self> {
if !sensor_util::check_digital_channel(channel) {
return Err(HalError(0));
}
let handle = hal_call!(HAL_InitializeDIOPort(
HAL_GetPort(channel as i32),
false as i32 ))?;
report_usage(resource_types::DigitalOutput, channel as instances::Type);
Ok(DigitalOutput {
channel,
handle,
pwm: None,
})
}
pub fn set_pwm_rate(rate: f64) -> HalResult<()> {
hal_call!(HAL_SetDigitalPWMRate(rate))
}
pub fn set(&mut self, value: bool) -> HalResult<()> {
hal_call!(HAL_SetDIO(self.handle, value as i32))
}
pub fn get(&self) -> HalResult<bool> {
Ok(hal_call!(HAL_GetDIO(self.handle))? != 0)
}
pub fn channel(&self) -> i32 {
self.channel
}
pub fn handle(&self) -> HAL_DigitalHandle {
self.handle
}
pub fn pulse(&mut self, length: f64) -> HalResult<()> {
hal_call!(HAL_Pulse(self.handle, length))
}
pub fn is_pulsing(&self) -> HalResult<bool> {
Ok(hal_call!(HAL_IsPulsing(self.handle))? != 0)
}
pub fn enable_pwm(&mut self, initial_duty_cycle: f64) -> HalResult<()> {
let pwm = hal_call!(HAL_AllocateDigitalPWM())?;
hal_call!(HAL_SetDigitalPWMDutyCycle(pwm, initial_duty_cycle))?;
hal_call!(HAL_SetDigitalPWMOutputChannel(pwm, self.channel))?;
self.pwm = Some(pwm);
Ok(())
}
pub fn disable_pwm(&mut self) -> HalResult<()> {
if let Some(pwm) = self.pwm {
hal_call!(HAL_SetDigitalPWMOutputChannel(
pwm,
*sensor_util::NUM_DIGITAL_CHANNELS
))?;
hal_call!(HAL_FreeDigitalPWM(pwm))?;
self.pwm = None;
}
Ok(())
}
pub fn update_duty_cycle(&mut self, duty_cycle: f64) -> HalResult<()> {
if let Some(pwm) = self.pwm {
hal_call!(HAL_SetDigitalPWMDutyCycle(pwm, duty_cycle))
} else {
Ok(())
}
}
}
impl Drop for DigitalOutput {
fn drop(&mut self) {
let _ = self.disable_pwm();
unsafe {
HAL_FreeDIOPort(self.handle);
}
}
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct DigitalInput {
channel: i32,
handle: HAL_DigitalHandle,
}
impl DigitalInput {
#[allow(clippy::new_ret_no_self)]
pub fn new(channel: i32) -> HalResult<Self> {
if !sensor_util::check_digital_channel(channel) {
return Err(HalError(0));
}
let handle = hal_call!(HAL_InitializeDIOPort(
HAL_GetPort(channel as i32),
true as i32 ))?;
report_usage(resource_types::DigitalInput, channel as instances::Type);
Ok(DigitalInput { channel, handle })
}
pub fn get(&self) -> HalResult<bool> {
Ok(hal_call!(HAL_GetDIO(self.handle))? != 0)
}
pub fn handle(&self) -> HAL_DigitalHandle {
self.handle
}
pub fn channel(&self) -> i32 {
self.channel
}
}
impl Drop for DigitalInput {
fn drop(&mut self) {
unsafe {
HAL_FreeDIOPort(self.handle);
}
}
}