Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Merge pull request #90 from Tropix126/feat/adi-addrled-solenoid
Browse files Browse the repository at this point in the history
fix: Configure ADI devices, `AdiAnalogOut` -> `AdiPwmOut`
  • Loading branch information
Gavin-Niederman authored Feb 14, 2024
2 parents a950fc8 + 747c20c commit e04bb07
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 72 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Before releasing:
- Refactors `AdiMotor` to match the smart motor APIs, having output/raw output getters/setters.
- Renamed `AdiUltrasonic::value` to `AdiUltrasonic::distance` (**Breaking Change**) (#61).
- Renamed `AdiEncoder::value` to `AdiEncoder::position` (**Breaking Change**) (#61).
- Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90).

### Removed

Expand Down
66 changes: 11 additions & 55 deletions packages/pros/src/devices/adi/analog.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Analog input and output ADI devices.
//! ADI Analog Interfaces
//!
//! # Overview
//!
Expand All @@ -21,8 +21,16 @@ pub struct AdiAnalogIn {

impl AdiAnalogIn {
/// Create a analog input from an ADI port.
pub const fn new(port: AdiPort) -> Self {
Self { port }
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_ANALOG_IN,
)
});

Ok(Self { port })
}

/// Calibrates the analog sensor on the specified channel.
Expand Down Expand Up @@ -129,55 +137,3 @@ impl AdiDevice for AdiAnalogIn {
AdiDeviceType::AnalogIn
}
}

/// Generic analog output ADI device.
#[derive(Debug, Eq, PartialEq)]
pub struct AdiAnalogOut {
port: AdiPort,
}

impl AdiAnalogOut {
/// Create a analog output from an [`AdiPort`].
pub const fn new(port: AdiPort) -> Self {
Self { port }
}

/// Sets the output for the Analog Output from 0 (0V) to 4095 (5V).
pub fn set_value(&mut self, value: u16) -> Result<(), AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_value(
self.port.internal_expander_index(),
self.port.index(),
value as i32,
)
});

Ok(())
}

/// Sets the output for the Analog Output from 0V to (5V).
///
/// # Precision
///
/// This function has a precision of `5.0/4095.0` volts, as ADC reports 12-bit voltage data
/// on a scale of 0-4095.
pub fn set_voltage(&mut self, value: f64) -> Result<(), AdiError> {
self.set_value((value / 5.0 * 4095.0) as u16)
}
}

impl AdiDevice for AdiAnalogOut {
type PortIndexOutput = u8;

fn port_index(&self) -> Self::PortIndexOutput {
self.port.index()
}

fn expander_port_index(&self) -> Option<u8> {
self.port.expander_index()
}

fn device_type(&self) -> AdiDeviceType {
AdiDeviceType::AnalogOut
}
}
24 changes: 20 additions & 4 deletions packages/pros/src/devices/adi/digital.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,16 @@ pub struct AdiDigitalIn {

impl AdiDigitalIn {
/// Create a digital input from an ADI port.
pub const fn new(port: AdiPort) -> Self {
Self { port }
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_DIGITAL_IN,
)
});

Ok(Self { port })
}

/// Gets the current logic level of a digital input pin.
Expand Down Expand Up @@ -112,8 +120,16 @@ pub struct AdiDigitalOut {

impl AdiDigitalOut {
/// Create a digital output from an [`AdiPort`].
pub const fn new(port: AdiPort) -> Self {
Self { port }
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_DIGITAL_OUT,
)
});

Ok(Self { port })
}

/// Sets the digital logic level (high or low) of a pin.
Expand Down
12 changes: 10 additions & 2 deletions packages/pros/src/devices/adi/linetracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,16 @@ pub struct AdiLineTracker {

impl AdiLineTracker {
/// Create a line tracker on an ADI port.
pub const fn new(port: AdiPort) -> Self {
Self { port }
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_ANALOG_IN,
)
});

Ok(Self { port })
}

/// Get the reflectivity factor measured by the sensor.
Expand Down
25 changes: 20 additions & 5 deletions packages/pros/src/devices/adi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::error::{bail_on, map_errno, PortError};
//TODO: much more in depth module documentation for device modules as well as this module.
pub mod analog;
pub mod digital;
pub mod pwm;

pub mod encoder;
pub mod gyro;
Expand Down Expand Up @@ -111,21 +112,35 @@ pub trait AdiDevice {
pub enum AdiDeviceType {
/// Generic analog input.
AnalogIn = pros_sys::adi::E_ADI_ANALOG_IN,
/// Generic analog output.
AnalogOut = pros_sys::adi::E_ADI_ANALOG_OUT,

/// Generic PWM output.
///
/// This is actually equivalent `pros_sys::adi::E_ADI_ANALOG_OUT`, which is a misnomer.
/// "Analog Out" in reality outputs an 8-bit PWM value.
PwmOut = pros_sys::adi::E_ADI_ANALOG_OUT,

/// Generic digital input.
DigitalIn = pros_sys::adi::E_ADI_DIGITAL_IN,

/// Generic digital output.
DigitalOut = pros_sys::adi::E_ADI_DIGITAL_OUT,

/// Cortex-era gyro.
/// Cortex-era yaw-rate gyroscope.
LegacyGyro = pros_sys::adi::E_ADI_LEGACY_GYRO,

/// Cortex-era servo motor.
LegacyServo = pros_sys::adi::E_ADI_LEGACY_SERVO,
/// PWM output.

/// MC29 Controller Output
///
/// This differs from [`Self::PwmOut`] in that it is specifically designed for controlling
/// legacy ADI motors. Rather than taking a u8 for output, it takes a i8 allowing negative
/// values to be sent for controlling motors in reverse with a nicer API.
LegacyPwm = pros_sys::adi::E_ADI_LEGACY_PWM,

/// Cortex-era encoder.
LegacyEncoder = pros_sys::E_ADI_LEGACY_ENCODER,

/// Cortex-era ultrasonic sensor.
LegacyUltrasonic = pros_sys::E_ADI_LEGACY_ULTRASONIC,
}
Expand All @@ -138,7 +153,7 @@ impl TryFrom<adi_port_config_e_t> for AdiDeviceType {

match value {
pros_sys::E_ADI_ANALOG_IN => Ok(AdiDeviceType::AnalogIn),
pros_sys::E_ADI_ANALOG_OUT => Ok(AdiDeviceType::AnalogOut),
pros_sys::E_ADI_ANALOG_OUT => Ok(AdiDeviceType::PwmOut),
pros_sys::E_ADI_DIGITAL_IN => Ok(AdiDeviceType::DigitalIn),
pros_sys::E_ADI_DIGITAL_OUT => Ok(AdiDeviceType::DigitalOut),

Expand Down
59 changes: 59 additions & 0 deletions packages/pros/src/devices/adi/pwm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//! ADI Pulse-width modulation (PWM).
use pros_sys::PROS_ERR;

use super::{AdiDevice, AdiDeviceType, AdiError, AdiPort};
use crate::error::bail_on;

/// Generic PWM output ADI device.
#[derive(Debug, Eq, PartialEq)]
pub struct AdiPwmOut {
port: AdiPort,
}

impl AdiPwmOut {
/// Create a pwm output from an [`AdiPort`].
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_ANALOG_OUT,
)
});

Ok(Self { port })
}

/// Sets the PWM output width.
///
/// This value is sent over 16ms periods with pulse widths ranging from roughly
/// 0.94mS to 2.03mS.
pub fn set_output(&mut self, value: u8) -> Result<(), AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_value(
self.port.internal_expander_index(),
self.port.index(),
value as i32,
)
});

Ok(())
}
}

impl AdiDevice for AdiPwmOut {
type PortIndexOutput = u8;

fn port_index(&self) -> Self::PortIndexOutput {
self.port.index()
}

fn expander_port_index(&self) -> Option<u8> {
self.port.expander_index()
}

fn device_type(&self) -> AdiDeviceType {
AdiDeviceType::PwmOut
}
}
14 changes: 11 additions & 3 deletions packages/pros/src/devices/adi/solenoid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@ pub struct AdiSolenoid {

impl AdiSolenoid {
/// Create an AdiSolenoid.
pub const fn new(port: AdiPort) -> Self {
Self {
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_DIGITAL_OUT,
)
});

Ok(Self {
port,
level: LogicLevel::Low,
}
})
}

/// Sets the digital logic level of the solenoid. [`LogicLevel::Low`] will close the solenoid,
Expand Down
12 changes: 10 additions & 2 deletions packages/pros/src/devices/adi/switch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,16 @@ pub struct AdiSwitch {

impl AdiSwitch {
/// Create a digital input from an ADI port.
pub const fn new(port: AdiPort) -> Self {
Self { port }
pub fn new(port: AdiPort) -> Result<Self, AdiError> {
bail_on!(PROS_ERR, unsafe {
pros_sys::ext_adi_port_set_config(
port.internal_expander_index(),
port.index(),
pros_sys::E_ADI_DIGITAL_IN,
)
});

Ok(Self { port })
}

/// Gets the current logic level of a digital switch.
Expand Down
3 changes: 2 additions & 1 deletion packages/pros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,13 @@ pub mod prelude {
color::Rgb,
devices::{
adi::{
analog::{AdiAnalogIn, AdiAnalogOut},
analog::AdiAnalogIn,
digital::{AdiDigitalIn, AdiDigitalOut},
encoder::AdiEncoder,
gyro::AdiGyro,
motor::AdiMotor,
potentiometer::{AdiPotentiometer, AdiPotentiometerType},
pwm::AdiPwmOut,
solenoid::AdiSolenoid,
ultrasonic::AdiUltrasonic,
AdiDevice, AdiPort,
Expand Down

0 comments on commit e04bb07

Please sign in to comment.