aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2023-11-02 21:52:01 +0000
committerGitHub <[email protected]>2023-11-02 21:52:01 +0000
commit7ea2c3508a38a4ec92761f4ebaeebbbc0cb6d331 (patch)
tree1d9c7a081b6f7b30344960db35649ac99df73b66 /examples
parent1b9292dbcde3ad23c6a235ff2b04d544bda54334 (diff)
parentec744558b200aebbb05e4d0db89197fea86a25f4 (diff)
Merge pull request #2137 from kalkyl/pio-rotary-encoder
rp: Add PIO rotary encoder example
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/pio_rotary_encoder.rs81
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
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::gpio::Pull;
10use embassy_rp::peripherals::PIO0;
11use embassy_rp::{bind_interrupts, pio};
12use fixed::traits::ToFixed;
13use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
14use {defmt_rtt as _, panic_probe as _};
15
16bind_interrupts!(struct Irqs {
17 PIO0_IRQ_0 => InterruptHandler<PIO0>;
18});
19
20pub struct PioEncoder<'d, T: Instance, const SM: usize> {
21 sm: StateMachine<'d, T, SM>,
22}
23
24impl<'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
61pub enum Direction {
62 Clockwise,
63 CounterClockwise,
64}
65
66#[embassy_executor::main]
67async 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}