aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp/src/pio_programs/rotary_encoder.rs
diff options
context:
space:
mode:
authorCaleb Jamison <[email protected]>2024-10-09 10:04:35 -0400
committerCaleb Jamison <[email protected]>2024-10-09 10:18:00 -0400
commit57c1fbf3089e2a2dc9fe5b7d1f1e094596566395 (patch)
tree833856b7da855b8de56dec1494c2da88ac29e415 /embassy-rp/src/pio_programs/rotary_encoder.rs
parent456c226b29799f7db56ab60b0ae3d95cc7d6a32a (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.rs72
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
3use crate::gpio::Pull;
4use crate::pio::{self, Common, Config, FifoJoin, Instance, LoadedProgram, PioPin, ShiftDirection, StateMachine};
5use fixed::traits::ToFixed;
6
7/// This struct represents an Encoder program loaded into pio instruction memory.
8pub struct PioEncoderProgram<'a, PIO: Instance> {
9 prg: LoadedProgram<'a, PIO>,
10}
11
12impl<'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
24pub struct PioEncoder<'d, T: Instance, const SM: usize> {
25 sm: StateMachine<'d, T, SM>,
26}
27
28impl<'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
67pub enum Direction {
68 /// Encoder turned clockwise
69 Clockwise,
70 /// Encoder turned counter clockwise
71 CounterClockwise,
72}