Skip to main content

pololu_smc/
variable_types.rs

1//! Defines the types that represent the values of non-trivial and non-numerical variables.
2
3/// Error flags that are stopping the motor from running.
4///
5/// The motor can only be driven when all of these flags are `false`
6#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
7pub struct Errors {
8    /// Safe start violation.
9    pub safe_start_violation: bool,
10    /// Required channel invalid.
11    pub required_channel_invalid: bool,
12    /// Serial error.
13    pub serial_error: bool,
14    /// Command timeout.
15    pub command_timeout: bool,
16    /// Limit/kill switch.
17    pub limit_kill_switch: bool,
18    /// Low VIN.
19    pub low_vin: bool,
20    /// High VIN.
21    pub high_vin: bool,
22    /// Over temperature.
23    pub over_temperature: bool,
24    /// Motor driver error.
25    pub motor_driver_error: bool,
26    /// ERR line high.
27    pub err_line_high: bool,
28}
29
30/// Serial errors
31#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
32pub struct SerialErrors {
33    /// Frame
34    pub frame: bool,
35    /// Noise
36    pub noise: bool,
37    /// RX overrun
38    pub rx_overrun: bool,
39    /// Format
40    pub format: bool,
41    /// CRC
42    pub crc: bool,
43}
44
45/// Flags that indicate things that are currently limiting the motor controller.
46#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
47pub struct Limits {
48    /// Motor is not allowed to run due to an error or safe-start violation.
49    pub motor_not_allowed_to_run: bool,
50    /// Temperate is actively reducing target speed.
51    pub temperature_reducing_speed: bool,
52    /// Max speed limit is actively reducing target speed (target speed > max speed).
53    pub max_speed: bool,
54    /// Starting speed limit is actively reducing target speed to zero (target speed < starting speed).
55    pub below_starting_speed: bool,
56    /// Motor speed is not equal to target speed because of acceleration, deceleration, or brake duration limits.
57    pub speed_limited_acc_dec_brakeduration: bool,
58    /// RC1 is configured as a limit/kill switch and the switch is active (scaled value >= 1600).
59    pub rc1_killswitch_active: bool,
60    /// RC2 is configured as a limit/kill switch and the switch is active (scaled value >= 1600).
61    pub rc2_killswitch_active: bool,
62    /// AN1 is configured as a limit/kill switch and the switch is active (scaled value >= 1600).
63    pub an1_killswitch_active: bool,
64    /// AN2 is configured as a limit/kill switch and the switch is active (scaled value >= 1600).
65    pub an2_killswitch_active: bool,
66    /// USB kill switch is active.
67    pub usb_killswitch_active: bool,
68}
69
70/// Reasons for why the controller board was reset
71#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
72pub enum ResetSource {
73    /// <span style="text-decoration:overline">RST</span> pin was pulled low by external source
74    NRstPulledLow,
75    /// Power reset (VIN got too low or was disconnected)
76    PowerLow,
77    /// Software reset (by firmware upgrade process)
78    SoftwareReset,
79    /// Watchdog timer reset (should never happen; this could indicate a firmware bug)
80    WatchdogTimer,
81    /// Controller returned a value not specified in the offical user's guide.
82    Unknown,
83}
84
85/// If the motor is braking or coasting.
86#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
87pub enum BrakeAmount {
88    /// Motor is coasting.
89    Coasting,
90    /// Motor is braking.
91    Braking,
92    /// Speed is not zero, so no brake amount is reported.
93    NotAvailable,
94    /// Controller returned a value not specified in the offical user's guide.
95    Unknown,
96}
97
98
99
100fn is_bit_set(byte: u16, bit: u8) -> bool {
101    byte & (1 << bit) != 0
102}
103
104impl From<u16> for Errors {
105    fn from(response: u16) -> Self {
106        Self {
107            safe_start_violation: is_bit_set(response, 0),
108            required_channel_invalid: is_bit_set(response, 1),
109            serial_error: is_bit_set(response, 2),
110            command_timeout: is_bit_set(response, 3),
111            limit_kill_switch: is_bit_set(response, 4),
112            low_vin: is_bit_set(response, 5),
113            high_vin: is_bit_set(response, 6),
114            over_temperature: is_bit_set(response, 7),
115            motor_driver_error: is_bit_set(response, 0),
116            err_line_high: is_bit_set(response, 1),
117        }
118    }
119}
120
121impl From<u16> for SerialErrors {
122    fn from(response: u16) -> Self {
123        Self {
124            frame: is_bit_set(response, 1),
125            noise: is_bit_set(response, 2),
126            rx_overrun: is_bit_set(response, 3),
127            format: is_bit_set(response, 4),
128            crc: is_bit_set(response, 5),
129        }
130    }
131}
132
133impl From<u16> for Limits {
134    fn from(response: u16) -> Self {
135        Self {
136            motor_not_allowed_to_run: is_bit_set(response, 0),
137            temperature_reducing_speed: is_bit_set(response, 1),
138            max_speed: is_bit_set(response, 2),
139            below_starting_speed: is_bit_set(response, 3),
140            speed_limited_acc_dec_brakeduration: is_bit_set(response, 4),
141            rc1_killswitch_active: is_bit_set(response, 5),
142            rc2_killswitch_active: is_bit_set(response, 6),
143            an1_killswitch_active: is_bit_set(response, 7),
144            an2_killswitch_active: is_bit_set(response, 8),
145            usb_killswitch_active: is_bit_set(response, 9),
146        }
147    }
148}
149
150impl From<u16> for ResetSource {
151    fn from(response: u16) -> Self {
152        match response {
153            0x04 => ResetSource::NRstPulledLow,
154            0x0c => ResetSource::PowerLow,
155            0x14 => ResetSource::SoftwareReset,
156            0x24 => ResetSource::WatchdogTimer,
157            _ => ResetSource::Unknown,
158        }
159    }
160}
161
162impl From<u16> for BrakeAmount {
163    fn from(response: u16) -> Self {
164        match response {
165            0 => BrakeAmount::Coasting,
166            32 => BrakeAmount::Braking,
167            0xff => BrakeAmount::NotAvailable,
168            _ => BrakeAmount::Unknown,
169        }
170    }
171}
172