ft_hal_generic/drivers/
ft_output_pair.rs

1use core::marker::PhantomData;
2
3use crate::{
4    ft_motor::{validate_speed, FtMotor},
5    ft_output::{FtOutput, FtOutputCommand},
6};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
9pub enum MotorError<OUT1Error, OUT2Error> {
10    InvalidSpeed,
11    Output1Error(OUT1Error),
12    Output2Error(OUT2Error),
13}
14
15/// A pair of FtOutput instances that can be used as a motor.
16pub struct FtOutputPair<O1, O2, E1, E2>
17where
18    O1: FtOutput<E1>,
19    O2: FtOutput<E2>,
20{
21    output1: O1,
22    output2: O2,
23
24    _err1: PhantomData<E1>,
25    _err2: PhantomData<E2>,
26}
27
28impl<O1, O2, E1, E2> FtOutputPair<O1, O2, E1, E2>
29where
30    O1: FtOutput<E1>,
31    O2: FtOutput<E2>,
32{
33    pub fn new(output1: O1, output2: O2) -> Self {
34        FtOutputPair {
35            output1,
36            output2,
37            _err1: PhantomData,
38            _err2: PhantomData,
39        }
40    }
41
42    pub fn into_motor(self) -> impl FtMotor<MotorError<E1, E2>> {
43        self
44    }
45}
46
47impl<O1, O2, E1, E2> FtMotor<MotorError<E1, E2>> for FtOutputPair<O1, O2, E1, E2>
48where
49    O1: FtOutput<E1>,
50    O2: FtOutput<E2>,
51{
52    fn forward(&mut self, speed: u8) -> Result<(), MotorError<E1, E2>> {
53        validate_speed(speed).map_err(|_| MotorError::InvalidSpeed)?;
54        self.output1
55            .turn_on(speed)
56            .map_err(MotorError::Output1Error)?;
57        self.output2
58            .set_output(FtOutputCommand::Low)
59            .map_err(MotorError::Output2Error)?;
60        Ok(())
61    }
62
63    fn backward(&mut self, speed: u8) -> Result<(), MotorError<E1, E2>> {
64        validate_speed(speed).map_err(|_| MotorError::InvalidSpeed)?;
65        self.output1
66            .set_output(FtOutputCommand::Low)
67            .map_err(MotorError::Output1Error)?;
68        self.output2
69            .turn_on(speed)
70            .map_err(MotorError::Output2Error)?;
71        Ok(())
72    }
73
74    fn coast(&mut self) -> Result<(), MotorError<E1, E2>> {
75        self.output1
76            .turn_off()
77            .map_err(MotorError::Output1Error)?;
78        self.output2
79            .turn_off()
80            .map_err(MotorError::Output2Error)?;
81        Ok(())
82    }
83
84    fn stop(&mut self) -> Result<(), MotorError<E1, E2>> {
85        self.output1
86            .set_output(FtOutputCommand::Low)
87            .map_err(MotorError::Output1Error)?;
88        self.output2
89            .set_output(FtOutputCommand::Low)
90            .map_err(MotorError::Output2Error)?;
91        Ok(())
92    }
93}