stepper/drivers/
stspin220.rs

1//! STSPIN220 Driver
2//!
3//! Platform-agnostic driver API for the STSPIN220 stepper motor driver. Can be
4//! used on any platform for which implementations of the required
5//! [embedded-hal] traits are available.
6//!
7//! For the most part, users are not expected to use this API directly. Please
8//! check out [`Stepper`](crate::Stepper) instead.
9//!
10//! [embedded-hal]: https://crates.io/crates/embedded-hal
11
12use core::convert::Infallible;
13
14use embedded_hal::digital::{blocking::OutputPin, PinState};
15use fugit::NanosDurationU32 as Nanoseconds;
16
17use crate::{
18    step_mode::StepMode256,
19    traits::{
20        EnableDirectionControl, EnableStepControl, EnableStepModeControl,
21        SetDirection, SetStepMode, Step,
22    },
23};
24
25/// The STSPIN220 driver API
26///
27/// Users are not expected to use this API directly, except to create an
28/// instance using [`STSPIN220::new`]. Please check out
29/// [`Stepper`](crate::Stepper) instead.
30pub struct STSPIN220<
31    EnableFault,
32    StandbyReset,
33    Mode1,
34    Mode2,
35    StepMode3,
36    DirMode4,
37> {
38    enable_fault: EnableFault,
39    standby_reset: StandbyReset,
40    mode1: Mode1,
41    mode2: Mode2,
42    step_mode3: StepMode3,
43    dir_mode4: DirMode4,
44}
45
46impl STSPIN220<(), (), (), (), (), ()> {
47    /// Create a new instance of `STSPIN220`
48    pub fn new() -> Self {
49        Self {
50            enable_fault: (),
51            standby_reset: (),
52            mode1: (),
53            mode2: (),
54            step_mode3: (),
55            dir_mode4: (),
56        }
57    }
58}
59
60impl<
61        EnableFault,
62        StandbyReset,
63        Mode1,
64        Mode2,
65        StepMode3,
66        DirMode4,
67        OutputPinError,
68    > EnableStepModeControl<(StandbyReset, Mode1, Mode2)>
69    for STSPIN220<EnableFault, (), (), (), StepMode3, DirMode4>
70where
71    StandbyReset: OutputPin<Error = OutputPinError>,
72    Mode1: OutputPin<Error = OutputPinError>,
73    Mode2: OutputPin<Error = OutputPinError>,
74    StepMode3: OutputPin<Error = OutputPinError>,
75    DirMode4: OutputPin<Error = OutputPinError>,
76{
77    type WithStepModeControl =
78        STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>;
79
80    fn enable_step_mode_control(
81        self,
82        (standby_reset, mode1, mode2): (StandbyReset, Mode1, Mode2),
83    ) -> Self::WithStepModeControl {
84        STSPIN220 {
85            enable_fault: self.enable_fault,
86            standby_reset,
87            mode1,
88            mode2,
89            step_mode3: self.step_mode3,
90            dir_mode4: self.dir_mode4,
91        }
92    }
93}
94
95impl<
96        EnableFault,
97        StandbyReset,
98        Mode1,
99        Mode2,
100        StepMode3,
101        DirMode4,
102        OutputPinError,
103    > SetStepMode
104    for STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>
105where
106    StandbyReset: OutputPin<Error = OutputPinError>,
107    Mode1: OutputPin<Error = OutputPinError>,
108    Mode2: OutputPin<Error = OutputPinError>,
109    StepMode3: OutputPin<Error = OutputPinError>,
110    DirMode4: OutputPin<Error = OutputPinError>,
111{
112    const SETUP_TIME: Nanoseconds = Nanoseconds::from_ticks(1_000);
113    const HOLD_TIME: Nanoseconds = Nanoseconds::from_ticks(100_000);
114
115    type Error = OutputPinError;
116    type StepMode = StepMode256;
117
118    fn apply_mode_config(
119        &mut self,
120        step_mode: Self::StepMode,
121    ) -> Result<(), Self::Error> {
122        // Force driver into standby mode.
123        self.standby_reset.set_low()?;
124
125        use PinState::*;
126        use StepMode256::*;
127        let (mode1, mode2, mode3, mode4) = match step_mode {
128            Full => (Low, Low, Low, Low),
129            M2 => (High, Low, High, Low),
130            M4 => (Low, High, Low, High),
131            M8 => (High, High, High, Low),
132            M16 => (High, High, High, High),
133            M32 => (Low, High, Low, Low),
134            M64 => (High, High, Low, High),
135            M128 => (High, Low, Low, Low),
136            M256 => (High, High, Low, Low),
137        };
138
139        // Set mode signals.
140        self.mode1.set_state(mode1)?;
141        self.mode2.set_state(mode2)?;
142        self.step_mode3.set_state(mode3)?;
143        self.dir_mode4.set_state(mode4)?;
144
145        Ok(())
146    }
147
148    fn enable_driver(&mut self) -> Result<(), Self::Error> {
149        // Leave standby mode.
150        self.standby_reset.set_high()
151    }
152}
153
154impl<
155        EnableFault,
156        StandbyReset,
157        Mode1,
158        Mode2,
159        StepMode3,
160        DirMode4,
161        OutputPinError,
162    > EnableDirectionControl<DirMode4>
163    for STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, ()>
164where
165    DirMode4: OutputPin<Error = OutputPinError>,
166{
167    type WithDirectionControl =
168        STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>;
169
170    fn enable_direction_control(
171        self,
172        dir_mode4: DirMode4,
173    ) -> Self::WithDirectionControl {
174        STSPIN220 {
175            enable_fault: self.enable_fault,
176            standby_reset: self.standby_reset,
177            mode1: self.mode1,
178            mode2: self.mode2,
179            step_mode3: self.step_mode3,
180            dir_mode4,
181        }
182    }
183}
184
185impl<
186        EnableFault,
187        StandbyReset,
188        Mode1,
189        Mode2,
190        StepMode3,
191        DirMode4,
192        OutputPinError,
193    > SetDirection
194    for STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>
195where
196    DirMode4: OutputPin<Error = OutputPinError>,
197{
198    const SETUP_TIME: Nanoseconds = Nanoseconds::from_ticks(100);
199
200    type Dir = DirMode4;
201    type Error = Infallible;
202
203    fn dir(&mut self) -> Result<&mut Self::Dir, Self::Error> {
204        Ok(&mut self.dir_mode4)
205    }
206}
207
208impl<
209        EnableFault,
210        StandbyReset,
211        Mode1,
212        Mode2,
213        StepMode3,
214        DirMode4,
215        OutputPinError,
216    > EnableStepControl<StepMode3>
217    for STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, (), DirMode4>
218where
219    StepMode3: OutputPin<Error = OutputPinError>,
220{
221    type WithStepControl =
222        STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>;
223
224    fn enable_step_control(
225        self,
226        step_mode3: StepMode3,
227    ) -> Self::WithStepControl {
228        STSPIN220 {
229            enable_fault: self.enable_fault,
230            standby_reset: self.standby_reset,
231            mode1: self.mode1,
232            mode2: self.mode2,
233            step_mode3,
234            dir_mode4: self.dir_mode4,
235        }
236    }
237}
238
239impl<
240        EnableFault,
241        StandbyReset,
242        Mode1,
243        Mode2,
244        StepMode3,
245        DirMode4,
246        OutputPinError,
247    > Step
248    for STSPIN220<EnableFault, StandbyReset, Mode1, Mode2, StepMode3, DirMode4>
249where
250    StepMode3: OutputPin<Error = OutputPinError>,
251{
252    const PULSE_LENGTH: Nanoseconds = Nanoseconds::from_ticks(100);
253
254    type Step = StepMode3;
255    type Error = Infallible;
256
257    fn step(&mut self) -> Result<&mut Self::Step, Self::Error> {
258        Ok(&mut self.step_mode3)
259    }
260}