diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-11-02 21:52:01 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-02 21:52:01 +0000 |
| commit | 7ea2c3508a38a4ec92761f4ebaeebbbc0cb6d331 (patch) | |
| tree | 1d9c7a081b6f7b30344960db35649ac99df73b66 /examples/rp | |
| parent | 1b9292dbcde3ad23c6a235ff2b04d544bda54334 (diff) | |
| parent | ec744558b200aebbb05e4d0db89197fea86a25f4 (diff) | |
Merge pull request #2137 from kalkyl/pio-rotary-encoder
rp: Add PIO rotary encoder example
Diffstat (limited to 'examples/rp')
| -rw-r--r-- | examples/rp/src/bin/pio_rotary_encoder.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/examples/rp/src/bin/pio_rotary_encoder.rs b/examples/rp/src/bin/pio_rotary_encoder.rs new file mode 100644 index 000000000..6d9d59df6 --- /dev/null +++ b/examples/rp/src/bin/pio_rotary_encoder.rs | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | //! This example shows how to use the PIO module in the RP2040 to read a quadrature rotary encoder. | ||
| 2 | |||
| 3 | #![no_std] | ||
| 4 | #![no_main] | ||
| 5 | #![feature(type_alias_impl_trait)] | ||
| 6 | |||
| 7 | use defmt::info; | ||
| 8 | use embassy_executor::Spawner; | ||
| 9 | use embassy_rp::gpio::Pull; | ||
| 10 | use embassy_rp::peripherals::PIO0; | ||
| 11 | use embassy_rp::{bind_interrupts, pio}; | ||
| 12 | use fixed::traits::ToFixed; | ||
| 13 | use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine}; | ||
| 14 | use {defmt_rtt as _, panic_probe as _}; | ||
| 15 | |||
| 16 | bind_interrupts!(struct Irqs { | ||
| 17 | PIO0_IRQ_0 => InterruptHandler<PIO0>; | ||
| 18 | }); | ||
| 19 | |||
| 20 | pub struct PioEncoder<'d, T: Instance, const SM: usize> { | ||
| 21 | sm: StateMachine<'d, T, SM>, | ||
| 22 | } | ||
| 23 | |||
| 24 | impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> { | ||
| 25 | pub fn new( | ||
| 26 | pio: &mut Common<'d, T>, | ||
| 27 | mut sm: StateMachine<'d, T, SM>, | ||
| 28 | pin_a: impl PioPin, | ||
| 29 | pin_b: impl PioPin, | ||
| 30 | ) -> Self { | ||
| 31 | let mut pin_a = pio.make_pio_pin(pin_a); | ||
| 32 | let mut pin_b = pio.make_pio_pin(pin_b); | ||
| 33 | pin_a.set_pull(Pull::Up); | ||
| 34 | pin_b.set_pull(Pull::Up); | ||
| 35 | sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]); | ||
| 36 | |||
| 37 | let prg = pio_proc::pio_asm!("wait 1 pin 1", "wait 0 pin 1", "in pins, 2", "push",); | ||
| 38 | |||
| 39 | let mut cfg = Config::default(); | ||
| 40 | cfg.set_in_pins(&[&pin_a, &pin_b]); | ||
| 41 | cfg.fifo_join = FifoJoin::RxOnly; | ||
| 42 | cfg.shift_in.direction = ShiftDirection::Left; | ||
| 43 | cfg.clock_divider = 10_000.to_fixed(); | ||
| 44 | cfg.use_program(&pio.load_program(&prg.program), &[]); | ||
| 45 | sm.set_config(&cfg); | ||
| 46 | sm.set_enable(true); | ||
| 47 | Self { sm } | ||
| 48 | } | ||
| 49 | |||
| 50 | pub async fn read(&mut self) -> Direction { | ||
| 51 | loop { | ||
| 52 | match self.sm.rx().wait_pull().await { | ||
| 53 | 0 => return Direction::CounterClockwise, | ||
| 54 | 1 => return Direction::Clockwise, | ||
| 55 | _ => {} | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | pub enum Direction { | ||
| 62 | Clockwise, | ||
| 63 | CounterClockwise, | ||
| 64 | } | ||
| 65 | |||
| 66 | #[embassy_executor::main] | ||
| 67 | async fn main(_spawner: Spawner) { | ||
| 68 | let p = embassy_rp::init(Default::default()); | ||
| 69 | let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs); | ||
| 70 | |||
| 71 | let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5); | ||
| 72 | |||
| 73 | let mut count = 0; | ||
| 74 | loop { | ||
| 75 | info!("Count: {}", count); | ||
| 76 | count += match encoder.read().await { | ||
| 77 | Direction::Clockwise => 1, | ||
| 78 | Direction::CounterClockwise => -1, | ||
| 79 | }; | ||
| 80 | } | ||
| 81 | } | ||
