diff options
| author | Caleb Jamison <[email protected]> | 2024-10-09 10:04:35 -0400 |
|---|---|---|
| committer | Caleb Jamison <[email protected]> | 2024-10-09 10:18:00 -0400 |
| commit | 57c1fbf3089e2a2dc9fe5b7d1f1e094596566395 (patch) | |
| tree | 833856b7da855b8de56dec1494c2da88ac29e415 /embassy-rp/src/pio_programs/rotary_encoder.rs | |
| parent | 456c226b29799f7db56ab60b0ae3d95cc7d6a32a (diff) | |
Move pio programs into embassy-rp
Diffstat (limited to 'embassy-rp/src/pio_programs/rotary_encoder.rs')
| -rw-r--r-- | embassy-rp/src/pio_programs/rotary_encoder.rs | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/embassy-rp/src/pio_programs/rotary_encoder.rs b/embassy-rp/src/pio_programs/rotary_encoder.rs new file mode 100644 index 000000000..323f839bc --- /dev/null +++ b/embassy-rp/src/pio_programs/rotary_encoder.rs | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | //! PIO backed quadrature encoder | ||
| 2 | |||
| 3 | use crate::gpio::Pull; | ||
| 4 | use crate::pio::{self, Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine}; | ||
| 5 | use fixed::traits::ToFixed; | ||
| 6 | |||
| 7 | /// This struct represents an Encoder program loaded into pio instruction memory. | ||
| 8 | pub struct PioEncoderProgram<'a, PIO: Instance> { | ||
| 9 | prg: LoadedProgram<'a, PIO>, | ||
| 10 | } | ||
| 11 | |||
| 12 | impl<'a, PIO: Instance> PioEncoderProgram<'a, PIO> { | ||
| 13 | /// Load the program into the given pio | ||
| 14 | pub fn new(common: &mut Common<'a, PIO>) -> Self { | ||
| 15 | let prg = pio_proc::pio_asm!("wait 1 pin 1", "wait 0 pin 1", "in pins, 2", "push",); | ||
| 16 | |||
| 17 | let prg = common.load_program(&prg.program); | ||
| 18 | |||
| 19 | Self { prg } | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | /// Pio Backed quadrature encoder reader | ||
| 24 | pub struct PioEncoder<'d, T: Instance, const SM: usize> { | ||
| 25 | sm: StateMachine<'d, T, SM>, | ||
| 26 | } | ||
| 27 | |||
| 28 | impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { | ||
| 29 | /// Configure a state machine with the loaded [PioEncoderProgram] | ||
| 30 | pub fn new( | ||
| 31 | pio: &mut Common<'d, T>, | ||
| 32 | mut sm: StateMachine<'d, T, SM>, | ||
| 33 | pin_a: impl PioPin, | ||
| 34 | pin_b: impl PioPin, | ||
| 35 | program: &PioEncoderProgram<'d, T>, | ||
| 36 | ) -> Self { | ||
| 37 | let mut pin_a = pio.make_pio_pin(pin_a); | ||
| 38 | let mut pin_b = pio.make_pio_pin(pin_b); | ||
| 39 | pin_a.set_pull(Pull::Up); | ||
| 40 | pin_b.set_pull(Pull::Up); | ||
| 41 | sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]); | ||
| 42 | |||
| 43 | let mut cfg = Config::default(); | ||
| 44 | cfg.set_in_pins(&[&pin_a, &pin_b]); | ||
| 45 | cfg.fifo_join = FifoJoin::RxOnly; | ||
| 46 | cfg.shift_in.direction = ShiftDirection::Left; | ||
| 47 | cfg.clock_divider = 10_000.to_fixed(); | ||
| 48 | cfg.use_program(&program.prg, &[]); | ||
| 49 | sm.set_config(&cfg); | ||
| 50 | sm.set_enable(true); | ||
| 51 | Self { sm } | ||
| 52 | } | ||
| 53 | |||
| 54 | /// Read a single count from the encoder | ||
| 55 | pub async fn read(&mut self) -> Direction { | ||
| 56 | loop { | ||
| 57 | match self.sm.rx().wait_pull().await { | ||
| 58 | 0 => return Direction::CounterClockwise, | ||
| 59 | 1 => return Direction::Clockwise, | ||
| 60 | _ => {} | ||
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | /// Encoder Count Direction | ||
| 67 | pub enum Direction { | ||
| 68 | /// Encoder turned clockwise | ||
| 69 | Clockwise, | ||
| 70 | /// Encoder turned counter clockwise | ||
| 71 | CounterClockwise, | ||
| 72 | } | ||
