drs_0x01/
addr.rs

1//! All the servomotor addresses mapped to some enums.
2
3use try_from::TryFrom;
4
5/// This enum represent all the RAM (volatile) memory adresses which can be read. I comes from the
6/// page 24 of the datasheet.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum ReadableRamAddr {
9    /// Servo ID
10    ID,
11    /// TODO : Refer to pg 33
12    AckPolicy,
13    /// Activates LED according to Policy
14    AlarmLEDPolicy,
15    /// Releases Torque accroding to Policy
16    TorquePolicy,
17    /// Maximum allowed temperature (0xDF = 85°C)
18    MaxTemperature,
19    /// Minimum allowed voltage (0x5B = 6.714 VDC)
20    MinVoltage,
21    /// Maximum allowed voltage (0x89 = 10 VDC)
22    MaxVoltage,
23    /// Ratio of time to reach goal position to acceleration or deceleration
24    AccelerationRatio,
25    /// Max acceleration time, 11.2ms interval. Acceleration(0x2D : 504 ms)
26    MaxAcceleration,
27    /// Outside controle range
28    DeadZone,
29    /// TODO : Refer to datasheet page 36
30    SaturatorOffset,
31    /// TODO : Refer to datasheet page 36
32    SaturatorSlope,
33    /// PWM Offset value, refer to datasheet page 37
34    PWMOffset,
35    /// Set minimum PWM value, refer to the datasheet page 37
36    MinPWM,
37    /// Set maximum PWM value, refer to the datasheet page 37
38    MaxPWM,
39    /// Set PWM Overload thershold range, refer to the datasheet page 34
40    OverloadPWMThreshold,
41    /// Minimum position value (between 0 and 1023)
42    MinPosition,
43    /// Maximum position value (between 0 and 1023)
44    MaxPosition,
45    /// Proportional gain
46    PositionKp,
47    /// Derivative gain
48    PositionKd,
49    /// Integral gain
50    PositionKi,
51    /// Refer to the datasheet page 35
52    PositionFFFirstGain,
53    /// Refer to the datasheet page 35
54    PositionFFSecondGain,
55    /// Alarm LED blink period according to Policy 11.2ms/Tick (0x2D : 504 ms)
56    LedBlinkPeriod,
57    /// Temp/Voltage error check interval. 11.2ms/tick (0x2D : 504 ms)
58    ADCFaultDetectionPeriod,
59    /// Packet error check interval. 11.2ms/tick (0x12 : 201 ms)
60    PacketGarbageDetectionPeriod,
61    /// Stop detection check interval. 11.2ms/tick (0x1B : 302 ms)
62    StopDetectionPeriod,
63    /// Overload check interbal. 11.2ms/tick (0x96 : 1.68 s)
64    OverloadDetectionPeriod,
65    /// Stop Threshold
66    StopThreshold,
67    /// Offset Threshold
68    InpositionMargin,
69    /// Servo compensation
70    CalibrationDifference,
71    /// Refer to datasheet page 39
72    StatusError,
73    /// Refer to datasheet page 39
74    StatusDetail,
75    /// Torque enable states (refer to datasheet page 28)
76    TorqueControl,
77    /// 0x01 : Green, 0x02 : Blue, 0x04 : Red
78    LEDControl,
79    /// Input voltage raw data 8bit (refer to datasheet page 31)
80    Voltage,
81    /// Current temperature data 8bit (refer to datasheet page 31)
82    Temperature,
83    /// 0 : Position control
84    /// 1 : Turn/Velocity control
85    CurrentControlMode,
86    /// 11.2ms/tick
87    Tick,
88    /// Calibrated current position raw data, 10 bit.
89    CalibratedPosition,
90    /// Uncalibrated absolute position raw data.
91    AbsolutePosition,
92    /// Position change/11.2ms
93    DifferentialPosition,
94    /// Torque raw data
95    PWM,
96    /// Uncalibrated goal position raw data
97    AbsoluteGoalPosition,
98    /// Current intermediate goal position in trajectory
99    AbsoluteDesiredTrajectoryPosition,
100    /// Desired speed based on speed profile raw data
101    DesiredVelocity,
102}
103
104impl ReadableRamAddr {
105    /// Return the size in bytes of the value stocked at this address
106    pub fn bytes(self) -> u8 {
107        match self {
108            ReadableRamAddr::ID => 1,
109            ReadableRamAddr::AckPolicy => 1,
110            ReadableRamAddr::AlarmLEDPolicy => 1,
111            ReadableRamAddr::TorquePolicy => 1,
112            ReadableRamAddr::MaxTemperature => 1,
113            ReadableRamAddr::MinVoltage => 1,
114            ReadableRamAddr::MaxVoltage => 1,
115            ReadableRamAddr::AccelerationRatio => 1,
116            ReadableRamAddr::MaxAcceleration => 1,
117            ReadableRamAddr::DeadZone => 1,
118            ReadableRamAddr::SaturatorOffset => 1,
119            ReadableRamAddr::SaturatorSlope => 2,
120            ReadableRamAddr::PWMOffset => 1,
121            ReadableRamAddr::MinPWM => 1,
122            ReadableRamAddr::MaxPWM => 2,
123            ReadableRamAddr::OverloadPWMThreshold => 2,
124            ReadableRamAddr::MinPosition => 2,
125            ReadableRamAddr::MaxPosition => 2,
126            ReadableRamAddr::PositionKp => 2,
127            ReadableRamAddr::PositionKd => 2,
128            ReadableRamAddr::PositionKi => 2,
129            ReadableRamAddr::PositionFFFirstGain => 2,
130            ReadableRamAddr::PositionFFSecondGain => 2,
131            ReadableRamAddr::LedBlinkPeriod => 1,
132            ReadableRamAddr::ADCFaultDetectionPeriod => 1,
133            ReadableRamAddr::PacketGarbageDetectionPeriod => 1,
134            ReadableRamAddr::StopDetectionPeriod => 1,
135            ReadableRamAddr::OverloadDetectionPeriod => 1,
136            ReadableRamAddr::StopThreshold => 1,
137            ReadableRamAddr::InpositionMargin => 1,
138            ReadableRamAddr::CalibrationDifference => 1,
139            ReadableRamAddr::StatusError => 1,
140            ReadableRamAddr::StatusDetail => 1,
141            ReadableRamAddr::TorqueControl => 1,
142            ReadableRamAddr::LEDControl => 1,
143            ReadableRamAddr::Voltage => 2,
144            ReadableRamAddr::Temperature => 2,
145            ReadableRamAddr::CurrentControlMode => 2,
146            ReadableRamAddr::Tick => 2,
147            ReadableRamAddr::CalibratedPosition => 2,
148            ReadableRamAddr::AbsolutePosition => 2,
149            ReadableRamAddr::DifferentialPosition => 2,
150            ReadableRamAddr::PWM => 2,
151            ReadableRamAddr::AbsoluteGoalPosition => 2,
152            ReadableRamAddr::AbsoluteDesiredTrajectoryPosition => 2,
153            ReadableRamAddr::DesiredVelocity => 1,
154        }
155    }
156}
157
158/// Data read from a servomotor
159#[derive(Debug, Clone, Copy, PartialEq, Eq)]
160pub struct RamReadData {
161    /// The addr from which the data was read
162    pub addr: ReadableRamAddr,
163    /// The number of data read at this address
164    pub data_len: u8,
165    /// The data read
166    pub data: [u8; 2],
167}
168
169/// This enum represent all the RAM (volatile) memory addresses which can be written to. I comes
170/// from the page 24 of the
171/// datasheet.
172#[derive(Clone, Copy, Debug, PartialEq, Eq)]
173pub enum WritableRamAddr {
174    /// Servo ID
175    ID(u8),
176    /// TODO : Refer to pg 33
177    AckPolicy(u8),
178    /// Activates LED according to Policy
179    AlarmLEDPolicy(u8),
180    /// Releases Torque accroding to Policy
181    TorquePolicy(u8),
182    /// Maximum allowed temperature (0xDF = 85°C)
183    MaxTemperature(u8),
184    /// Minimum allowed voltage (0x5B = 6.714 VDC)
185    MinVoltage(u8),
186    /// Maximum allowed voltage (0x89 = 10 VDC)
187    MaxVoltage(u8),
188    /// Ratio of time to reach goal position to acceleration or deceleration
189    AccelerationRatio(u8),
190    /// Max acceleration time, 11.2ms interval. Acceleration(0x2D : 504 ms)
191    MaxAcceleration(u8),
192    /// Outside controle range
193    DeadZone(u8),
194    /// TODO : Refer to datasheet page 36
195    SaturatorOffset(u8),
196    /// TODO : Refer to datasheet page 36
197    SaturatorSlope(u8, u8),
198    /// PWM Offset value, refer to datasheet page 37
199    PWMOffset(u8),
200    /// Set minimum PWM value, refer to the datasheet page 37
201    MinPWM(u8),
202    /// Set maximum PWM value, refer to the datasheet page 37
203    MaxPWM(u8, u8),
204    /// Set PWM Overload thershold range, refer to the datasheet page 34
205    OverloadPWMThreshold(u8, u8),
206    /// Minimum position value (between 0 and 1023)
207    MinPosition(u8, u8),
208    /// Maximum position value (between 0 and 1023)
209    MaxPosition(u8, u8),
210    /// Proportional gain
211    PositionKp(u8, u8),
212    /// Derivative gain
213    PositionKd(u8, u8),
214    /// Integral gain
215    PositionKi(u8, u8),
216    /// Refer to the datasheet page 35
217    PositionFFFirstGain(u8, u8),
218    /// Refer to the datasheet page 35
219    PositionFFSecondGain(u8, u8),
220    /// Alarm LED blink period according to Policy 11.2ms/Tick (0x2D : 504 ms)
221    LedBlinkPeriod(u8),
222    /// Temp/Voltage error check interval. 11.2ms/tick (0x2D : 504 ms)
223    ADCFaultDetectionPeriod(u8),
224    /// Packet error check interval. 11.2ms/tick (0x12 : 201 ms)
225    PacketGarbageDetectionPeriod(u8),
226    /// Stop detection check interval. 11.2ms/tick (0x1B : 302 ms)
227    StopDetectionPeriod(u8),
228    /// Overload check interbal. 11.2ms/tick (0x96 : 1.68 s)
229    OverloadDetectionPeriod(u8),
230    /// Stop Threshold
231    StopThreshold(u8),
232    /// Offset Threshold
233    InpositionMargin(u8),
234    /// Servo compensation
235    CalibrationDifference(u8),
236    /// Refer to datasheet page 39
237    StatusError(u8),
238    /// Refer to datasheet page 39
239    StatusDetail(u8),
240    /// Torque enable states (refer to datasheet page 28)
241    TorqueControl(u8),
242    /// 0x01 : Green, 0x02 : Blue, 0x04 : Red
243    LEDControl(u8),
244}
245
246impl WritableRamAddr {
247    /// Return the size in bytes of the value stocked at this address
248    pub fn bytes(self) -> u8 {
249        match self {
250            WritableRamAddr::ID(_) => 1,
251            WritableRamAddr::AckPolicy(_) => 1,
252            WritableRamAddr::AlarmLEDPolicy(_) => 1,
253            WritableRamAddr::TorquePolicy(_) => 1,
254            WritableRamAddr::MaxTemperature(_) => 1,
255            WritableRamAddr::MinVoltage(_) => 1,
256            WritableRamAddr::MaxVoltage(_) => 1,
257            WritableRamAddr::AccelerationRatio(_) => 1,
258            WritableRamAddr::MaxAcceleration(_) => 1,
259            WritableRamAddr::DeadZone(_) => 1,
260            WritableRamAddr::SaturatorOffset(_) => 1,
261            WritableRamAddr::SaturatorSlope(_, _) => 2,
262            WritableRamAddr::PWMOffset(_) => 1,
263            WritableRamAddr::MinPWM(_) => 1,
264            WritableRamAddr::MaxPWM(_, _) => 2,
265            WritableRamAddr::OverloadPWMThreshold(_, _) => 2,
266            WritableRamAddr::MinPosition(_, _) => 2,
267            WritableRamAddr::MaxPosition(_, _) => 2,
268            WritableRamAddr::PositionKp(_, _) => 2,
269            WritableRamAddr::PositionKd(_, _) => 2,
270            WritableRamAddr::PositionKi(_, _) => 2,
271            WritableRamAddr::PositionFFFirstGain(_, _) => 2,
272            WritableRamAddr::PositionFFSecondGain(_, _) => 2,
273            WritableRamAddr::LedBlinkPeriod(_) => 1,
274            WritableRamAddr::ADCFaultDetectionPeriod(_) => 1,
275            WritableRamAddr::PacketGarbageDetectionPeriod(_) => 1,
276            WritableRamAddr::StopDetectionPeriod(_) => 1,
277            WritableRamAddr::OverloadDetectionPeriod(_) => 1,
278            WritableRamAddr::StopThreshold(_) => 1,
279            WritableRamAddr::InpositionMargin(_) => 1,
280            WritableRamAddr::CalibrationDifference(_) => 1,
281            WritableRamAddr::StatusError(_) => 1,
282            WritableRamAddr::StatusDetail(_) => 1,
283            WritableRamAddr::TorqueControl(_) => 1,
284            WritableRamAddr::LEDControl(_) => 1,
285        }
286    }
287
288    pub(crate) fn associated_data(self) -> (u8, Option<u8>) {
289        match self {
290            WritableRamAddr::ID(d) => (d, None),
291            WritableRamAddr::AckPolicy(d) => (d, None),
292            WritableRamAddr::AlarmLEDPolicy(d) => (d, None),
293            WritableRamAddr::TorquePolicy(d) => (d, None),
294            WritableRamAddr::MaxTemperature(d) => (d, None),
295            WritableRamAddr::MinVoltage(d) => (d, None),
296            WritableRamAddr::MaxVoltage(d) => (d, None),
297            WritableRamAddr::AccelerationRatio(d) => (d, None),
298            WritableRamAddr::MaxAcceleration(d) => (d, None),
299            WritableRamAddr::DeadZone(d) => (d, None),
300            WritableRamAddr::SaturatorOffset(d) => (d, None),
301            WritableRamAddr::SaturatorSlope(d, d2) => (d, Some(d2)),
302            WritableRamAddr::PWMOffset(d) => (d, None),
303            WritableRamAddr::MinPWM(d) => (d, None),
304            WritableRamAddr::MaxPWM(d, d2) => (d, Some(d2)),
305            WritableRamAddr::OverloadPWMThreshold(d, d2) => (d, Some(d2)),
306            WritableRamAddr::MinPosition(d, d2) => (d, Some(d2)),
307            WritableRamAddr::MaxPosition(d, d2) => (d, Some(d2)),
308            WritableRamAddr::PositionKp(d, d2) => (d, Some(d2)),
309            WritableRamAddr::PositionKd(d, d2) => (d, Some(d2)),
310            WritableRamAddr::PositionKi(d, d2) => (d, Some(d2)),
311            WritableRamAddr::PositionFFFirstGain(d, d2) => (d, Some(d2)),
312            WritableRamAddr::PositionFFSecondGain(d, d2) => (d, Some(d2)),
313            WritableRamAddr::LedBlinkPeriod(d) => (d, None),
314            WritableRamAddr::ADCFaultDetectionPeriod(d) => (d, None),
315            WritableRamAddr::PacketGarbageDetectionPeriod(d) => (d, None),
316            WritableRamAddr::StopDetectionPeriod(d) => (d, None),
317            WritableRamAddr::OverloadDetectionPeriod(d) => (d, None),
318            WritableRamAddr::StopThreshold(d) => (d, None),
319            WritableRamAddr::InpositionMargin(d) => (d, None),
320            WritableRamAddr::CalibrationDifference(d) => (d, None),
321            WritableRamAddr::StatusError(d) => (d, None),
322            WritableRamAddr::StatusDetail(d) => (d, None),
323            WritableRamAddr::TorqueControl(d) => (d, None),
324            WritableRamAddr::LEDControl(d) => (d, None),
325        }
326    }
327}
328
329impl From<ReadableRamAddr> for u8 {
330    fn from(addr: ReadableRamAddr) -> Self {
331        use addr::ReadableRamAddr::*;
332        match addr {
333            ID => 0,
334            AckPolicy => 1,
335            AlarmLEDPolicy => 2,
336            TorquePolicy => 3,
337            MaxTemperature => 5,
338            MinVoltage => 6,
339            MaxVoltage => 7,
340            AccelerationRatio => 8,
341            MaxAcceleration => 9,
342            DeadZone => 10,
343            SaturatorOffset => 11,
344            SaturatorSlope => 12,
345            PWMOffset => 14,
346            MinPWM => 15,
347            MaxPWM => 16,
348            OverloadPWMThreshold => 18,
349            MinPosition => 20,
350            MaxPosition => 22,
351            PositionKp => 24,
352            PositionKd => 26,
353            PositionKi => 28,
354            PositionFFFirstGain => 30,
355            PositionFFSecondGain => 32,
356            LedBlinkPeriod => 38,
357            ADCFaultDetectionPeriod => 39,
358            PacketGarbageDetectionPeriod => 40,
359            StopDetectionPeriod => 41,
360            OverloadDetectionPeriod => 42,
361            StopThreshold => 43,
362            InpositionMargin => 44,
363            CalibrationDifference => 47,
364            StatusError => 48,
365            StatusDetail => 49,
366            TorqueControl => 52,
367            LEDControl => 53,
368            Voltage => 54,
369            Temperature => 55,
370            CurrentControlMode => 56,
371            Tick => 57,
372            CalibratedPosition => 58,
373            AbsolutePosition => 60,
374            DifferentialPosition => 62,
375            PWM => 64,
376            AbsoluteGoalPosition => 68,
377            AbsoluteDesiredTrajectoryPosition => 70,
378            DesiredVelocity => 72,
379        }
380    }
381}
382
383impl TryFrom<u8> for ReadableRamAddr {
384    type Err = Error;
385    fn try_from(addr: u8) -> Result<ReadableRamAddr, Error> {
386        match addr {
387            0 => Ok(ReadableRamAddr::ID),
388            1 => Ok(ReadableRamAddr::AckPolicy),
389            2 => Ok(ReadableRamAddr::AlarmLEDPolicy),
390            3 => Ok(ReadableRamAddr::TorquePolicy),
391            5 => Ok(ReadableRamAddr::MaxTemperature),
392            6 => Ok(ReadableRamAddr::MinVoltage),
393            7 => Ok(ReadableRamAddr::MaxVoltage),
394            8 => Ok(ReadableRamAddr::AccelerationRatio),
395            9 => Ok(ReadableRamAddr::MaxAcceleration),
396            10 => Ok(ReadableRamAddr::DeadZone),
397            11 => Ok(ReadableRamAddr::SaturatorOffset),
398            12 => Ok(ReadableRamAddr::SaturatorSlope),
399            14 => Ok(ReadableRamAddr::PWMOffset),
400            15 => Ok(ReadableRamAddr::MinPWM),
401            16 => Ok(ReadableRamAddr::MaxPWM),
402            18 => Ok(ReadableRamAddr::OverloadPWMThreshold),
403            20 => Ok(ReadableRamAddr::MinPosition),
404            22 => Ok(ReadableRamAddr::MaxPosition),
405            24 => Ok(ReadableRamAddr::PositionKp),
406            26 => Ok(ReadableRamAddr::PositionKd),
407            28 => Ok(ReadableRamAddr::PositionKi),
408            30 => Ok(ReadableRamAddr::PositionFFFirstGain),
409            32 => Ok(ReadableRamAddr::PositionFFSecondGain),
410            38 => Ok(ReadableRamAddr::LedBlinkPeriod),
411            39 => Ok(ReadableRamAddr::ADCFaultDetectionPeriod),
412            40 => Ok(ReadableRamAddr::PacketGarbageDetectionPeriod),
413            41 => Ok(ReadableRamAddr::StopDetectionPeriod),
414            42 => Ok(ReadableRamAddr::OverloadDetectionPeriod),
415            43 => Ok(ReadableRamAddr::StopThreshold),
416            44 => Ok(ReadableRamAddr::InpositionMargin),
417            47 => Ok(ReadableRamAddr::CalibrationDifference),
418            48 => Ok(ReadableRamAddr::StatusError),
419            49 => Ok(ReadableRamAddr::StatusDetail),
420            52 => Ok(ReadableRamAddr::TorqueControl),
421            53 => Ok(ReadableRamAddr::LEDControl),
422            54 => Ok(ReadableRamAddr::Voltage),
423            55 => Ok(ReadableRamAddr::Temperature),
424            56 => Ok(ReadableRamAddr::CurrentControlMode),
425            57 => Ok(ReadableRamAddr::Tick),
426            58 => Ok(ReadableRamAddr::CalibratedPosition),
427            60 => Ok(ReadableRamAddr::AbsolutePosition),
428            62 => Ok(ReadableRamAddr::DifferentialPosition),
429            64 => Ok(ReadableRamAddr::PWM),
430            68 => Ok(ReadableRamAddr::AbsoluteGoalPosition),
431            70 => Ok(ReadableRamAddr::AbsoluteDesiredTrajectoryPosition),
432            72 => Ok(ReadableRamAddr::DesiredVelocity),
433            _ => Err(Error::InvalidAddress),
434        }
435    }
436}
437
438impl From<WritableRamAddr> for u8 {
439    fn from(addr: WritableRamAddr) -> Self {
440        use addr::WritableRamAddr::*;
441        match addr {
442            ID(_) => 0,
443            AckPolicy(_) => 1,
444            AlarmLEDPolicy(_) => 2,
445            TorquePolicy(_) => 3,
446            MaxTemperature(_) => 5,
447            MinVoltage(_) => 6,
448            MaxVoltage(_) => 7,
449            AccelerationRatio(_) => 8,
450            MaxAcceleration(_) => 9,
451            DeadZone(_) => 10,
452            SaturatorOffset(_) => 11,
453            SaturatorSlope(_, _) => 12,
454            PWMOffset(_) => 14,
455            MinPWM(_) => 15,
456            MaxPWM(_, _) => 16,
457            OverloadPWMThreshold(_, _) => 18,
458            MinPosition(_, _) => 20,
459            MaxPosition(_, _) => 22,
460            PositionKp(_, _) => 24,
461            PositionKd(_, _) => 26,
462            PositionKi(_, _) => 28,
463            PositionFFFirstGain(_, _) => 30,
464            PositionFFSecondGain(_, _) => 32,
465            LedBlinkPeriod(_) => 38,
466            ADCFaultDetectionPeriod(_) => 39,
467            PacketGarbageDetectionPeriod(_) => 40,
468            StopDetectionPeriod(_) => 41,
469            OverloadDetectionPeriod(_) => 42,
470            StopThreshold(_) => 43,
471            InpositionMargin(_) => 44,
472            CalibrationDifference(_) => 47,
473            StatusError(_) => 48,
474            StatusDetail(_) => 49,
475            TorqueControl(_) => 52,
476            LEDControl(_) => 53,
477        }
478    }
479}
480
481impl TryFrom<u8> for WritableRamAddr {
482    type Err = Error;
483    fn try_from(addr: u8) -> Result<WritableRamAddr, Error> {
484        match addr {
485            0 => Ok(WritableRamAddr::ID(0)),
486            1 => Ok(WritableRamAddr::AckPolicy(0)),
487            2 => Ok(WritableRamAddr::AlarmLEDPolicy(0)),
488            3 => Ok(WritableRamAddr::TorquePolicy(0)),
489            5 => Ok(WritableRamAddr::MaxTemperature(0)),
490            6 => Ok(WritableRamAddr::MinVoltage(0)),
491            7 => Ok(WritableRamAddr::MaxVoltage(0)),
492            8 => Ok(WritableRamAddr::AccelerationRatio(0)),
493            9 => Ok(WritableRamAddr::MaxAcceleration(0)),
494            10 => Ok(WritableRamAddr::DeadZone(0)),
495            11 => Ok(WritableRamAddr::SaturatorOffset(0)),
496            12 => Ok(WritableRamAddr::SaturatorSlope(0, 0)),
497            14 => Ok(WritableRamAddr::PWMOffset(0)),
498            15 => Ok(WritableRamAddr::MinPWM(0)),
499            16 => Ok(WritableRamAddr::MaxPWM(0, 0)),
500            18 => Ok(WritableRamAddr::OverloadPWMThreshold(0, 0)),
501            20 => Ok(WritableRamAddr::MinPosition(0, 0)),
502            22 => Ok(WritableRamAddr::MaxPosition(0, 0)),
503            24 => Ok(WritableRamAddr::PositionKp(0, 0)),
504            26 => Ok(WritableRamAddr::PositionKd(0, 0)),
505            28 => Ok(WritableRamAddr::PositionKi(0, 0)),
506            30 => Ok(WritableRamAddr::PositionFFFirstGain(0, 0)),
507            32 => Ok(WritableRamAddr::PositionFFSecondGain(0, 0)),
508            38 => Ok(WritableRamAddr::LedBlinkPeriod(0)),
509            39 => Ok(WritableRamAddr::ADCFaultDetectionPeriod(0)),
510            40 => Ok(WritableRamAddr::PacketGarbageDetectionPeriod(0)),
511            41 => Ok(WritableRamAddr::StopDetectionPeriod(0)),
512            42 => Ok(WritableRamAddr::OverloadDetectionPeriod(0)),
513            43 => Ok(WritableRamAddr::StopThreshold(0)),
514            44 => Ok(WritableRamAddr::InpositionMargin(0)),
515            47 => Ok(WritableRamAddr::CalibrationDifference(0)),
516            48 => Ok(WritableRamAddr::StatusError(0)),
517            49 => Ok(WritableRamAddr::StatusDetail(0)),
518            52 => Ok(WritableRamAddr::TorqueControl(0)),
519            53 => Ok(WritableRamAddr::LEDControl(0)),
520            _ => Err(Error::InvalidAddress),
521        }
522    }
523}
524
525/// This enum represent all the EPP (permanent) memory addresses which can be read. I comes from
526/// the page 21 of the
527/// datasheet.
528#[derive(Clone, Copy, Debug, PartialEq, Eq)]
529pub enum ReadableEEPAddr {
530    /// DRS model number first byte
531    ModelNo1,
532    /// DRS model number second byte
533    ModelNo2,
534    /// Firmware version first byte
535    Version1,
536    /// Firmware version second byte
537    Version2,
538    /// Communication speed
539    BaudRate,
540    /// Servo ID
541    ID,
542    /// TODO : Refer to pg 33
543    AckPolicy,
544    /// Activates LED according to Policy
545    AlarmLEDPolicy,
546    /// Releases Torque accroding to Policy
547    TorquePolicy,
548    /// Maximum allowed temperature (0xDF = 85°C)
549    MaxTemperature,
550    /// Minimum allowed voltage (0x5B = 6.714 VDC)
551    MinVoltage,
552    /// Maximum allowed voltage (0x89 = 10 VDC)
553    MaxVoltage,
554    /// Ratio of time to reach goal position to acceleration or deceleration
555    AccelerationRatio,
556    /// Max acceleration time, 11.2ms interval. Acceleration(0x2D : 504 ms)
557    MaxAccelerationTime,
558    /// Outside controle range
559    DeadZone,
560    /// TODO : Refer to datasheet page 36
561    SaturatorOffset,
562    /// TODO : Refer to datasheet page 36
563    SaturatorSlope,
564    /// PWM Offset value, refer to datasheet page 37
565    PWMOffset,
566    /// Set minimum PWM value, refer to the datasheet page 37
567    MinPWM,
568    /// Set maximum PWM value, refer to the datasheet page 37
569    MaxPWM,
570    /// Set PWM Overload thershold range, refer to the datasheet page 34
571    OverloadPWMThreshold,
572    /// Minimum position value (between 0 and 1023)
573    MinPosition,
574    /// Maximum position value (between 0 and 1023)
575    MaxPosition,
576    /// Proportional gain
577    PositionKp,
578    /// Derivative gain
579    PositionKd,
580    /// Integral gain
581    PositionKi,
582    /// Refer to the datasheet page 35
583    PositionFFFirstGain,
584    /// Refer to the datasheet page 35
585    PositionFFSecondGain,
586    /// Alarm LED blink period according to Policy 11.2ms/Tick (0x2D : 504 ms)
587    LedBlinkPeriod,
588    /// Temp/Voltage error check interval. 11.2ms/tick (0x2D : 504 ms)
589    ADCFaultCheckPeriod,
590    /// Packet error check interval. 11.2ms/tick (0x12 : 201 ms)
591    PacketGarbageDetectionPeriod,
592    /// Stop detection check interval. 11.2ms/tick (0x1B : 302 ms)
593    StopDetectionPeriod,
594    /// Overload check interbal. 11.2ms/tick (0x96 : 1.68 s)
595    OverloadDetectionPeriod,
596    /// Stop Threshold
597    StopThreshold,
598    /// Offset Threshold
599    InpositionMargin,
600    /// Servo compensation
601    CalibrationDifference,
602}
603
604/// The data read from the EEP memory of the servomotor
605#[derive(Debug, Clone, Copy, PartialEq, Eq)]
606pub struct EEPReadData {
607    /// The address from which the data was read
608    pub addr: ReadableEEPAddr,
609    /// The size of the data read
610    pub data_len: u8,
611    /// The data read
612    pub data: [u8; 2],
613}
614
615impl ReadableEEPAddr {
616    /// Return the number of bytes associated with an address
617    pub fn bytes(self) -> u8 {
618        match self {
619            ReadableEEPAddr::ModelNo1 => 1,
620            ReadableEEPAddr::ModelNo2 => 1,
621            ReadableEEPAddr::Version1 => 1,
622            ReadableEEPAddr::Version2 => 1,
623            ReadableEEPAddr::BaudRate => 1,
624            ReadableEEPAddr::ID => 1,
625            ReadableEEPAddr::AckPolicy => 1,
626            ReadableEEPAddr::AlarmLEDPolicy => 1,
627            ReadableEEPAddr::TorquePolicy => 1,
628            ReadableEEPAddr::MaxTemperature => 1,
629            ReadableEEPAddr::MinVoltage => 1,
630            ReadableEEPAddr::MaxVoltage => 1,
631            ReadableEEPAddr::AccelerationRatio => 1,
632            ReadableEEPAddr::MaxAccelerationTime => 1,
633            ReadableEEPAddr::DeadZone => 1,
634            ReadableEEPAddr::SaturatorOffset => 1,
635            ReadableEEPAddr::SaturatorSlope => 2,
636            ReadableEEPAddr::PWMOffset => 1,
637            ReadableEEPAddr::MinPWM => 1,
638            ReadableEEPAddr::MaxPWM => 2,
639            ReadableEEPAddr::OverloadPWMThreshold => 2,
640            ReadableEEPAddr::MinPosition => 2,
641            ReadableEEPAddr::MaxPosition => 2,
642            ReadableEEPAddr::PositionKp => 2,
643            ReadableEEPAddr::PositionKd => 2,
644            ReadableEEPAddr::PositionKi => 2,
645            ReadableEEPAddr::PositionFFFirstGain => 2,
646            ReadableEEPAddr::PositionFFSecondGain => 2,
647            ReadableEEPAddr::LedBlinkPeriod => 1,
648            ReadableEEPAddr::ADCFaultCheckPeriod => 1,
649            ReadableEEPAddr::PacketGarbageDetectionPeriod => 1,
650            ReadableEEPAddr::StopDetectionPeriod => 1,
651            ReadableEEPAddr::OverloadDetectionPeriod => 1,
652            ReadableEEPAddr::StopThreshold => 1,
653            ReadableEEPAddr::InpositionMargin => 1,
654            ReadableEEPAddr::CalibrationDifference => 1,
655        }
656    }
657}
658
659impl From<ReadableEEPAddr> for u8 {
660    fn from(me: ReadableEEPAddr) -> Self {
661        match me {
662            ReadableEEPAddr::ModelNo1 => 0,
663            ReadableEEPAddr::ModelNo2 => 1,
664            ReadableEEPAddr::Version1 => 2,
665            ReadableEEPAddr::Version2 => 3,
666            ReadableEEPAddr::BaudRate => 4,
667            ReadableEEPAddr::ID => 6,
668            ReadableEEPAddr::AckPolicy => 7,
669            ReadableEEPAddr::AlarmLEDPolicy => 8,
670            ReadableEEPAddr::TorquePolicy => 9,
671            ReadableEEPAddr::MaxTemperature => 11,
672            ReadableEEPAddr::MinVoltage => 12,
673            ReadableEEPAddr::MaxVoltage => 13,
674            ReadableEEPAddr::AccelerationRatio => 14,
675            ReadableEEPAddr::MaxAccelerationTime => 15,
676            ReadableEEPAddr::DeadZone => 16,
677            ReadableEEPAddr::SaturatorOffset => 17,
678            ReadableEEPAddr::SaturatorSlope => 18,
679            ReadableEEPAddr::PWMOffset => 20,
680            ReadableEEPAddr::MinPWM => 21,
681            ReadableEEPAddr::MaxPWM => 22,
682            ReadableEEPAddr::OverloadPWMThreshold => 24,
683            ReadableEEPAddr::MinPosition => 26,
684            ReadableEEPAddr::MaxPosition => 28,
685            ReadableEEPAddr::PositionKp => 30,
686            ReadableEEPAddr::PositionKd => 32,
687            ReadableEEPAddr::PositionKi => 34,
688            ReadableEEPAddr::PositionFFFirstGain => 36,
689            ReadableEEPAddr::PositionFFSecondGain => 38,
690            ReadableEEPAddr::LedBlinkPeriod => 44,
691            ReadableEEPAddr::ADCFaultCheckPeriod => 45,
692            ReadableEEPAddr::PacketGarbageDetectionPeriod => 46,
693            ReadableEEPAddr::StopDetectionPeriod => 47,
694            ReadableEEPAddr::OverloadDetectionPeriod => 48,
695            ReadableEEPAddr::StopThreshold => 49,
696            ReadableEEPAddr::InpositionMargin => 50,
697            ReadableEEPAddr::CalibrationDifference => 53,
698        }
699    }
700}
701
702impl TryFrom<u8> for ReadableEEPAddr {
703    type Err = Error;
704    fn try_from(addr: u8) -> Result<ReadableEEPAddr, Error> {
705        match addr {
706            0 => Ok(ReadableEEPAddr::ModelNo1),
707            1 => Ok(ReadableEEPAddr::ModelNo2),
708            2 => Ok(ReadableEEPAddr::Version1),
709            3 => Ok(ReadableEEPAddr::Version2),
710            4 => Ok(ReadableEEPAddr::BaudRate),
711            6 => Ok(ReadableEEPAddr::ID),
712            7 => Ok(ReadableEEPAddr::AckPolicy),
713            8 => Ok(ReadableEEPAddr::AlarmLEDPolicy),
714            9 => Ok(ReadableEEPAddr::TorquePolicy),
715            11 => Ok(ReadableEEPAddr::MaxTemperature),
716            12 => Ok(ReadableEEPAddr::MinVoltage),
717            13 => Ok(ReadableEEPAddr::MaxVoltage),
718            14 => Ok(ReadableEEPAddr::AccelerationRatio),
719            15 => Ok(ReadableEEPAddr::MaxAccelerationTime),
720            16 => Ok(ReadableEEPAddr::DeadZone),
721            17 => Ok(ReadableEEPAddr::SaturatorOffset),
722            18 => Ok(ReadableEEPAddr::SaturatorSlope),
723            20 => Ok(ReadableEEPAddr::PWMOffset),
724            21 => Ok(ReadableEEPAddr::MinPWM),
725            22 => Ok(ReadableEEPAddr::MaxPWM),
726            24 => Ok(ReadableEEPAddr::OverloadPWMThreshold),
727            26 => Ok(ReadableEEPAddr::MinPosition),
728            28 => Ok(ReadableEEPAddr::MaxPosition),
729            30 => Ok(ReadableEEPAddr::PositionKp),
730            32 => Ok(ReadableEEPAddr::PositionKd),
731            34 => Ok(ReadableEEPAddr::PositionKi),
732            36 => Ok(ReadableEEPAddr::PositionFFFirstGain),
733            38 => Ok(ReadableEEPAddr::PositionFFSecondGain),
734            44 => Ok(ReadableEEPAddr::LedBlinkPeriod),
735            45 => Ok(ReadableEEPAddr::ADCFaultCheckPeriod),
736            46 => Ok(ReadableEEPAddr::PacketGarbageDetectionPeriod),
737            47 => Ok(ReadableEEPAddr::StopDetectionPeriod),
738            48 => Ok(ReadableEEPAddr::OverloadDetectionPeriod),
739            49 => Ok(ReadableEEPAddr::StopThreshold),
740            50 => Ok(ReadableEEPAddr::InpositionMargin),
741            53 => Ok(ReadableEEPAddr::CalibrationDifference),
742            _ => Err(Error::InvalidAddress),
743        }
744    }
745}
746
747#[derive(Clone, Copy, Debug, PartialEq)]
748/// This enum represent all the EPP (permanent) memory addresses which can be written to. I comes
749/// from the page 21 of the datasheet.
750pub enum WritableEEPAddr {
751    /// Communication speed
752    BaudRate(u8),
753    /// Servo ID
754    ID(u8),
755    /// TODO : Refer to pg 33
756    AckPolicy(u8),
757    /// Activates LED according to Policy
758    AlarmLEDPolicy(u8),
759    /// Releases Torque accroding to Policy
760    TorquePolicy(u8),
761    /// Maximum allowed temperature (0xDF = 85°C)
762    MaxTemperature(u8),
763    /// Minimum allowed voltage (0x5B = 6.714 VDC)
764    MinVoltage(u8),
765    /// Maximum allowed voltage (0x89 = 10 VDC)
766    MaxVoltage(u8),
767    /// Ratio of time to reach goal position to acceleration or deceleration
768    AccelerationRatio(u8),
769    /// Max acceleration time, 11.2ms interval. Acceleration(0x2D : 504 ms)
770    MaxAccelerationTime(u8),
771    /// Outside controle range
772    DeadZone(u8),
773    /// TODO : Refer to datasheet page 36
774    SaturatorOffset(u8),
775    /// TODO : Refer to datasheet page 36
776    SaturatorSlope(u8, u8),
777    /// PWM Offset value, refer to datasheet page 37
778    PWMOffset(u8),
779    /// Set minimum PWM value, refer to the datasheet page 37
780    MinPWM(u8),
781    /// Set maximum PWM value, refer to the datasheet page 37
782    MaxPWM(u8, u8),
783    /// Set PWM Overload thershold range, refer to the datasheet page 34
784    OverloadPWMThreshold(u8, u8),
785    /// Minimum position value (between 0 and 1023)
786    MinPosition(u8, u8),
787    /// Maximum position value (between 0 and 1023)
788    MaxPosition(u8, u8),
789    /// Proportional gain
790    PositionKp(u8, u8),
791    /// Derivative gain
792    PositionKd(u8, u8),
793    /// Integral gain
794    PositionKi(u8, u8),
795    /// Refer to the datasheet page 35
796    PositionFFFirstGain(u8, u8),
797    /// Refer to the datasheet page 35
798    PositionFFSecondGain(u8, u8),
799    /// Alarm LED blink period according to Policy 11.2ms/Tick (0x2D : 504 ms)
800    LedBlinkPeriod(u8),
801    /// Temp/Voltage error check interval. 11.2ms/tick (0x2D : 504 ms)
802    ADCFaultCheckPeriod(u8),
803    /// Packet error check interval. 11.2ms/tick (0x12 : 201 ms)
804    PacketGarbageDetectionPeriod(u8),
805    /// Stop detection check interval. 11.2ms/tick (0x1B : 302 ms)
806    StopDetectionPeriod(u8),
807    /// Overload check interbal. 11.2ms/tick (0x96 : 1.68 s)
808    OverloadDetectionPeriod(u8),
809    /// Stop Threshold
810    StopThreshold(u8),
811    /// Offset Threshold
812    InpositionMargin(u8),
813    /// Servo compensation
814    CalibrationDifference(u8),
815}
816
817impl From<WritableEEPAddr> for u8 {
818    fn from(me: WritableEEPAddr) -> Self {
819        match me {
820            WritableEEPAddr::BaudRate(_) => 4,
821            WritableEEPAddr::ID(_) => 6,
822            WritableEEPAddr::AckPolicy(_) => 7,
823            WritableEEPAddr::AlarmLEDPolicy(_) => 8,
824            WritableEEPAddr::TorquePolicy(_) => 9,
825            WritableEEPAddr::MaxTemperature(_) => 11,
826            WritableEEPAddr::MinVoltage(_) => 12,
827            WritableEEPAddr::MaxVoltage(_) => 13,
828            WritableEEPAddr::AccelerationRatio(_) => 14,
829            WritableEEPAddr::MaxAccelerationTime(_) => 15,
830            WritableEEPAddr::DeadZone(_) => 16,
831            WritableEEPAddr::SaturatorOffset(_) => 17,
832            WritableEEPAddr::SaturatorSlope(_, _) => 18,
833            WritableEEPAddr::PWMOffset(_) => 20,
834            WritableEEPAddr::MinPWM(_) => 21,
835            WritableEEPAddr::MaxPWM(_, _) => 22,
836            WritableEEPAddr::OverloadPWMThreshold(_, _) => 24,
837            WritableEEPAddr::MinPosition(_, _) => 26,
838            WritableEEPAddr::MaxPosition(_, _) => 28,
839            WritableEEPAddr::PositionKp(_, _) => 30,
840            WritableEEPAddr::PositionKd(_, _) => 32,
841            WritableEEPAddr::PositionKi(_, _) => 34,
842            WritableEEPAddr::PositionFFFirstGain(_, _) => 36,
843            WritableEEPAddr::PositionFFSecondGain(_, _) => 38,
844            WritableEEPAddr::LedBlinkPeriod(_) => 44,
845            WritableEEPAddr::ADCFaultCheckPeriod(_) => 45,
846            WritableEEPAddr::PacketGarbageDetectionPeriod(_) => 46,
847            WritableEEPAddr::StopDetectionPeriod(_) => 47,
848            WritableEEPAddr::OverloadDetectionPeriod(_) => 48,
849            WritableEEPAddr::StopThreshold(_) => 49,
850            WritableEEPAddr::InpositionMargin(_) => 50,
851            WritableEEPAddr::CalibrationDifference(_) => 53,
852        }
853    }
854}
855
856/// The conversion error when converting u8 to addresses.
857pub enum Error {
858    /// This integer does not map to a valid error
859    InvalidAddress,
860}
861
862impl TryFrom<u8> for WritableEEPAddr {
863    type Err = Error;
864    fn try_from(me: u8) -> Result<WritableEEPAddr, Error> {
865        match me {
866            4 => Ok(WritableEEPAddr::BaudRate(0)),
867            6 => Ok(WritableEEPAddr::ID(0)),
868            7 => Ok(WritableEEPAddr::AckPolicy(0)),
869            8 => Ok(WritableEEPAddr::AlarmLEDPolicy(0)),
870            9 => Ok(WritableEEPAddr::TorquePolicy(0)),
871            11 => Ok(WritableEEPAddr::MaxTemperature(0)),
872            12 => Ok(WritableEEPAddr::MinVoltage(0)),
873            13 => Ok(WritableEEPAddr::MaxVoltage(0)),
874            14 => Ok(WritableEEPAddr::AccelerationRatio(0)),
875            15 => Ok(WritableEEPAddr::MaxAccelerationTime(0)),
876            16 => Ok(WritableEEPAddr::DeadZone(0)),
877            17 => Ok(WritableEEPAddr::SaturatorOffset(0)),
878            18 => Ok(WritableEEPAddr::SaturatorSlope(0, 0)),
879            20 => Ok(WritableEEPAddr::PWMOffset(0)),
880            21 => Ok(WritableEEPAddr::MinPWM(0)),
881            22 => Ok(WritableEEPAddr::MaxPWM(0, 0)),
882            24 => Ok(WritableEEPAddr::OverloadPWMThreshold(0, 0)),
883            26 => Ok(WritableEEPAddr::MinPosition(0, 0)),
884            28 => Ok(WritableEEPAddr::MaxPosition(0, 0)),
885            30 => Ok(WritableEEPAddr::PositionKp(0, 0)),
886            32 => Ok(WritableEEPAddr::PositionKd(0, 0)),
887            34 => Ok(WritableEEPAddr::PositionKi(0, 0)),
888            36 => Ok(WritableEEPAddr::PositionFFFirstGain(0, 0)),
889            38 => Ok(WritableEEPAddr::PositionFFSecondGain(0, 0)),
890            44 => Ok(WritableEEPAddr::LedBlinkPeriod(0)),
891            45 => Ok(WritableEEPAddr::ADCFaultCheckPeriod(0)),
892            46 => Ok(WritableEEPAddr::PacketGarbageDetectionPeriod(0)),
893            47 => Ok(WritableEEPAddr::StopDetectionPeriod(0)),
894            48 => Ok(WritableEEPAddr::OverloadDetectionPeriod(0)),
895            49 => Ok(WritableEEPAddr::StopThreshold(0)),
896            50 => Ok(WritableEEPAddr::InpositionMargin(0)),
897            53 => Ok(WritableEEPAddr::CalibrationDifference(0)),
898            _ => Err(Error::InvalidAddress),
899        }
900    }
901}
902
903impl WritableEEPAddr {
904    /// Return the number of bytes associated with an address
905    pub fn bytes(self) -> u8 {
906        match self {
907            WritableEEPAddr::BaudRate(_) => 1,
908            WritableEEPAddr::ID(_) => 1,
909            WritableEEPAddr::AckPolicy(_) => 1,
910            WritableEEPAddr::AlarmLEDPolicy(_) => 1,
911            WritableEEPAddr::TorquePolicy(_) => 1,
912            WritableEEPAddr::MaxTemperature(_) => 1,
913            WritableEEPAddr::MinVoltage(_) => 1,
914            WritableEEPAddr::MaxVoltage(_) => 1,
915            WritableEEPAddr::AccelerationRatio(_) => 1,
916            WritableEEPAddr::MaxAccelerationTime(_) => 1,
917            WritableEEPAddr::DeadZone(_) => 1,
918            WritableEEPAddr::SaturatorOffset(_) => 1,
919            WritableEEPAddr::SaturatorSlope(_, _) => 2,
920            WritableEEPAddr::PWMOffset(_) => 1,
921            WritableEEPAddr::MinPWM(_) => 1,
922            WritableEEPAddr::MaxPWM(_, _) => 2,
923            WritableEEPAddr::OverloadPWMThreshold(_, _) => 2,
924            WritableEEPAddr::MinPosition(_, _) => 2,
925            WritableEEPAddr::MaxPosition(_, _) => 2,
926            WritableEEPAddr::PositionKp(_, _) => 2,
927            WritableEEPAddr::PositionKd(_, _) => 2,
928            WritableEEPAddr::PositionKi(_, _) => 2,
929            WritableEEPAddr::PositionFFFirstGain(_, _) => 2,
930            WritableEEPAddr::PositionFFSecondGain(_, _) => 2,
931            WritableEEPAddr::LedBlinkPeriod(_) => 1,
932            WritableEEPAddr::ADCFaultCheckPeriod(_) => 1,
933            WritableEEPAddr::PacketGarbageDetectionPeriod(_) => 1,
934            WritableEEPAddr::StopDetectionPeriod(_) => 1,
935            WritableEEPAddr::OverloadDetectionPeriod(_) => 1,
936            WritableEEPAddr::StopThreshold(_) => 1,
937            WritableEEPAddr::InpositionMargin(_) => 1,
938            WritableEEPAddr::CalibrationDifference(_) => 1,
939        }
940    }
941
942    pub(crate) fn associated_data(self) -> (u8, Option<u8>) {
943        match self {
944            WritableEEPAddr::BaudRate(d) => (d, None),
945            WritableEEPAddr::ID(d) => (d, None),
946            WritableEEPAddr::AckPolicy(d) => (d, None),
947            WritableEEPAddr::AlarmLEDPolicy(d) => (d, None),
948            WritableEEPAddr::TorquePolicy(d) => (d, None),
949            WritableEEPAddr::MaxTemperature(d) => (d, None),
950            WritableEEPAddr::MinVoltage(d) => (d, None),
951            WritableEEPAddr::MaxVoltage(d) => (d, None),
952            WritableEEPAddr::AccelerationRatio(d) => (d, None),
953            WritableEEPAddr::MaxAccelerationTime(d) => (d, None),
954            WritableEEPAddr::DeadZone(d) => (d, None),
955            WritableEEPAddr::SaturatorOffset(d) => (d, None),
956            WritableEEPAddr::SaturatorSlope(d, d2) => (d, Some(d2)),
957            WritableEEPAddr::PWMOffset(d) => (d, None),
958            WritableEEPAddr::MinPWM(d) => (d, None),
959            WritableEEPAddr::MaxPWM(d, d2) => (d, Some(d2)),
960            WritableEEPAddr::OverloadPWMThreshold(d, d2) => (d, Some(d2)),
961            WritableEEPAddr::MinPosition(d, d2) => (d, Some(d2)),
962            WritableEEPAddr::MaxPosition(d, d2) => (d, Some(d2)),
963            WritableEEPAddr::PositionKp(d, d2) => (d, Some(d2)),
964            WritableEEPAddr::PositionKd(d, d2) => (d, Some(d2)),
965            WritableEEPAddr::PositionKi(d, d2) => (d, Some(d2)),
966            WritableEEPAddr::PositionFFFirstGain(d, d2) => (d, Some(d2)),
967            WritableEEPAddr::PositionFFSecondGain(d, d2) => (d, Some(d2)),
968            WritableEEPAddr::LedBlinkPeriod(d) => (d, None),
969            WritableEEPAddr::ADCFaultCheckPeriod(d) => (d, None),
970            WritableEEPAddr::PacketGarbageDetectionPeriod(d) => (d, None),
971            WritableEEPAddr::StopDetectionPeriod(d) => (d, None),
972            WritableEEPAddr::OverloadDetectionPeriod(d) => (d, None),
973            WritableEEPAddr::StopThreshold(d) => (d, None),
974            WritableEEPAddr::InpositionMargin(d) => (d, None),
975            WritableEEPAddr::CalibrationDifference(d) => (d, None),
976        }
977    }
978}