Skip to content
Snippets Groups Projects
encoders.rs 2.06 KiB
Newer Older
use embassy_stm32::{
    peripherals::{PA0, PA1, PA6, PA7, TIM2, TIM3},
    timer::qei::{Direction, Qei, QeiPin},
Samuel Tardieu's avatar
Samuel Tardieu committed
};

pub struct Encoders<'a> {
    left: Qei<'a, TIM3>,
    right: Qei<'a, TIM2>,
Samuel Tardieu's avatar
Samuel Tardieu committed
}

pub struct EncoderValue {
    count: u16,
    direction: Direction,
}

pub struct Relative {
    count_left: u16,
    count_right: u16,
}

impl core::fmt::Debug for EncoderValue {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(
            f,
            "{} ({})",
            self.count,
            if matches!(self.direction, Direction::Upcounting) {
                "upcounting"
            } else {
                "downcounting"
            }
        )
    }
}

impl Encoders<'_> {
    pub fn new(pa0: PA0, pa1: PA1, pa6: PA6, pa7: PA7, tim2: TIM2, tim3: TIM3) -> Self {
        let left = Qei::new(tim3, QeiPin::new_ch1(pa6), QeiPin::new_ch2(pa7));
        let right = Qei::new(tim2, QeiPin::new_ch1(pa0), QeiPin::new_ch2(pa1));
        pac::TIM2.ccer().modify(|w| w.set_ccp(1, true));
        Self { left, right }
Samuel Tardieu's avatar
Samuel Tardieu committed
    }

    pub fn read(&self) -> (EncoderValue, EncoderValue) {
        (
            EncoderValue {
                count: self.left.count(),
                direction: self.left.read_direction(),
Samuel Tardieu's avatar
Samuel Tardieu committed
            },
            EncoderValue {
                count: self.right.count(),
                direction: self.right.read_direction(),
Samuel Tardieu's avatar
Samuel Tardieu committed
            },
        )
    }
}

impl Relative {
    pub fn new(encoders: &Encoders<'_>) -> Self {
        let (count_left, count_right) = (encoders.left.count(), encoders.right.count());
        Self {
            count_left,
            count_right,
        }
    }
Samuel Tardieu's avatar
Samuel Tardieu committed

    pub fn ticks(&mut self, encoders: &Encoders<'_>) -> (i16, i16) {
        let (left, right) = (encoders.left.count(), encoders.right.count());
Samuel Tardieu's avatar
Samuel Tardieu committed
        (
            ticks_since(&mut self.count_left, left),
            ticks_since(&mut self.count_right, right),
        )
    }
}

Samuel Tardieu's avatar
Samuel Tardieu committed
#[allow(clippy::cast_possible_wrap)]
Samuel Tardieu's avatar
Samuel Tardieu committed
fn ticks_since(old: &mut u16, new: u16) -> i16 {
    let diff = (new - *old) as i16;
    *old = new;
    diff
}