1use num_enum::{IntoPrimitive, TryFromPrimitive};
18
19#[non_exhaustive]
23#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, IntoPrimitive, TryFromPrimitive)]
24#[repr(u8)]
25pub enum Mode {
26 #[default]
28 Stopped = 0,
29 Fault = 1,
31 Enabling = 2,
33 Calibrating = 3,
35 CalibrationComplete = 4,
37 Pwm = 5,
39 Voltage = 6,
41 VoltageFoc = 7,
43 VoltageDq = 8,
45 Current = 9,
47 Position = 10,
49 Timeout = 11,
51 ZeroVelocity = 12,
53 StayWithin = 13,
55 MeasureInd = 14,
57 Brake = 15,
59}
60
61impl core::fmt::Display for Mode {
62 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
63 match self {
64 Mode::Stopped => write!(f, "stopped"),
65 Mode::Fault => write!(f, "fault"),
66 Mode::Enabling => write!(f, "enabling"),
67 Mode::Calibrating => write!(f, "calibrating"),
68 Mode::CalibrationComplete => write!(f, "calibration complete"),
69 Mode::Pwm => write!(f, "pwm"),
70 Mode::Voltage => write!(f, "voltage"),
71 Mode::VoltageFoc => write!(f, "voltage foc"),
72 Mode::VoltageDq => write!(f, "voltage dq"),
73 Mode::Current => write!(f, "current"),
74 Mode::Position => write!(f, "position"),
75 Mode::Timeout => write!(f, "timeout"),
76 Mode::ZeroVelocity => write!(f, "zero velocity"),
77 Mode::StayWithin => write!(f, "stay within"),
78 Mode::MeasureInd => write!(f, "measure inductance"),
79 Mode::Brake => write!(f, "brake"),
80 }
81 }
82}
83
84impl Mode {
85 pub fn is_error(&self) -> bool {
101 matches!(self, Mode::Fault | Mode::Timeout)
102 }
103
104 pub fn is_active(&self) -> bool {
106 matches!(
107 self,
108 Mode::Position
109 | Mode::Current
110 | Mode::VoltageFoc
111 | Mode::ZeroVelocity
112 | Mode::StayWithin
113 | Mode::Brake
114 )
115 }
116}
117
118impl From<Mode> for i8 {
119 fn from(mode: Mode) -> i8 {
120 let v: u8 = mode.into();
121 v as i8
122 }
123}
124
125#[non_exhaustive]
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, IntoPrimitive, TryFromPrimitive)]
130#[repr(u8)]
131pub enum HomeState {
132 #[default]
134 Relative = 0,
135 Rotor = 1,
137 Output = 2,
139}
140
141impl core::fmt::Display for HomeState {
142 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
143 match self {
144 HomeState::Relative => write!(f, "relative"),
145 HomeState::Rotor => write!(f, "rotor"),
146 HomeState::Output => write!(f, "output"),
147 }
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_mode_try_from() {
157 assert_eq!(Mode::try_from(0), Ok(Mode::Stopped));
158 assert_eq!(Mode::try_from(10), Ok(Mode::Position));
159 assert!(Mode::try_from(255).is_err());
160 }
161
162 #[test]
163 fn test_mode_into() {
164 let v: u8 = Mode::Position.into();
165 assert_eq!(v, 10);
166 }
167
168 #[test]
169 fn test_mode_is_error() {
170 assert!(Mode::Fault.is_error());
171 assert!(Mode::Timeout.is_error());
172 assert!(!Mode::Position.is_error());
173 assert!(!Mode::Stopped.is_error());
174 }
175
176 #[test]
177 fn test_mode_is_active() {
178 assert!(Mode::Position.is_active());
179 assert!(Mode::Current.is_active());
180 assert!(Mode::Brake.is_active());
181 assert!(!Mode::Stopped.is_active());
182 assert!(!Mode::Fault.is_active());
183 }
184
185 #[test]
186 fn test_home_state_try_from() {
187 assert_eq!(HomeState::try_from(0), Ok(HomeState::Relative));
188 assert_eq!(HomeState::try_from(2), Ok(HomeState::Output));
189 assert!(HomeState::try_from(3).is_err());
190 }
191
192 #[test]
193 fn test_home_state_into() {
194 let v: u8 = HomeState::Output.into();
195 assert_eq!(v, 2);
196 }
197}