accel_stepper/
hal_devices.rs

1use crate::{Device, StepContext};
2use embedded_hal::digital::v2::OutputPin;
3
4/// A [`Device`] which has step and direction pins.
5///
6/// Requires the `hal` feature.
7#[derive(Debug, Default, Clone, PartialEq)]
8pub struct StepAndDirection<Step, Direction> {
9    step: Step,
10    direction: Direction,
11}
12
13impl<Step, Direction> StepAndDirection<Step, Direction> {
14    pub fn new(step: Step, direction: Direction) -> Self {
15        StepAndDirection { step, direction }
16    }
17
18    pub fn into_inner(self) -> (Step, Direction) { (self.step, self.direction) }
19}
20
21fn set_output<P: OutputPin>(pin: &mut P, mask: u8) -> Result<(), P::Error> {
22    if mask != 0 {
23        pin.set_high()
24    } else {
25        pin.set_low()
26    }
27}
28
29impl<Step, Direction, E> StepAndDirection<Step, Direction>
30where
31    Step: OutputPin<Error = E>,
32    Direction: OutputPin<Error = E>,
33{
34    fn set_output(&mut self, mask: u8) -> Result<(), E> {
35        set_output(&mut self.step, mask & 0b01)?;
36        set_output(&mut self.direction, mask & 0b10)?;
37
38        Ok(())
39    }
40}
41
42impl<Step, Direction, E> Device for StepAndDirection<Step, Direction>
43where
44    Step: OutputPin<Error = E>,
45    Direction: OutputPin<Error = E>,
46{
47    type Error = E;
48
49    #[inline]
50    fn step(&mut self, ctx: &StepContext) -> Result<(), Self::Error> {
51        // copied straight from AccelStepper::step2()
52        match ctx.position & 0x03 {
53            0 => self.set_output(0b10),
54            1 => self.set_output(0b11),
55            2 => self.set_output(0b01),
56            3 => self.set_output(0b00),
57            _ => unreachable!(),
58        }
59    }
60}