aboutsummaryrefslogtreecommitdiff
path: root/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
diff options
context:
space:
mode:
authorCurly <[email protected]>2025-02-23 07:33:58 -0800
committerCurly <[email protected]>2025-02-23 07:33:58 -0800
commit3932835998802fc3abf7cce4f736e072858ebfd1 (patch)
tree5dd714b99bc74a03556c58809237c88691c293bb /examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
parentc3c67db93e627a4fafe5e1a1123e5cbb4abafe47 (diff)
rename `rp23` (?) folder to `rp235x`; fix `ci.sh` to use `rp235x` folder
Diffstat (limited to 'examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs')
-rw-r--r--examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs112
1 files changed, 112 insertions, 0 deletions
diff --git a/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
new file mode 100644
index 000000000..0216c131b
--- /dev/null
+++ b/examples/rp235x/src/bin/pio_rotary_encoder_rxf.rs
@@ -0,0 +1,112 @@
1//! This example shows how to use the PIO module in the RP235x to read a quadrature rotary encoder.
2//! It differs from the other example in that it uses the RX FIFO as a status register
3
4#![no_std]
5#![no_main]
6
7use defmt::info;
8use embassy_executor::Spawner;
9use embassy_rp::gpio::Pull;
10use embassy_rp::peripherals::PIO0;
11use embassy_rp::pio::program::pio_asm;
12use embassy_rp::{bind_interrupts, pio};
13use embassy_time::Timer;
14use fixed::traits::ToFixed;
15use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
16use {defmt_rtt as _, panic_probe as _};
17
18// Program metadata for `picotool info`
19#[link_section = ".bi_entries"]
20#[used]
21pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [
22 embassy_rp::binary_info::rp_program_name!(c"example_pio_rotary_encoder_rxf"),
23 embassy_rp::binary_info::rp_cargo_version!(),
24 embassy_rp::binary_info::rp_program_description!(c"Rotary encoder (RXF)"),
25 embassy_rp::binary_info::rp_program_build_attribute!(),
26];
27
28bind_interrupts!(struct Irqs {
29 PIO0_IRQ_0 => InterruptHandler<PIO0>;
30});
31
32pub struct PioEncoder<'d, T: Instance, const SM: usize> {
33 sm: StateMachine<'d, T, SM>,
34}
35
36impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
37 pub fn new(
38 pio: &mut Common<'d, T>,
39 mut sm: StateMachine<'d, T, SM>,
40 pin_a: impl PioPin,
41 pin_b: impl PioPin,
42 ) -> Self {
43 let mut pin_a = pio.make_pio_pin(pin_a);
44 let mut pin_b = pio.make_pio_pin(pin_b);
45 pin_a.set_pull(Pull::Up);
46 pin_b.set_pull(Pull::Up);
47
48 sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]);
49
50 let prg = pio_asm!(
51 "start:"
52 // encoder count is stored in X
53 "mov isr, x"
54 // and then moved to the RX FIFO register
55 "mov rxfifo[0], isr"
56
57 // wait for encoder transition
58 "wait 1 pin 1"
59 "wait 0 pin 1"
60
61 "set y, 0"
62 "mov y, pins[1]"
63
64 // update X depending on pin 1
65 "jmp !y decr"
66
67 // this is just a clever way of doing x++
68 "mov x, ~x"
69 "jmp x--, incr"
70 "incr:"
71 "mov x, ~x"
72 "jmp start"
73
74 // and this is x--
75 "decr:"
76 "jmp x--, start"
77 );
78
79 let mut cfg = Config::default();
80 cfg.set_in_pins(&[&pin_a, &pin_b]);
81 cfg.fifo_join = FifoJoin::RxAsStatus;
82 cfg.shift_in.direction = ShiftDirection::Left;
83 cfg.clock_divider = 10_000.to_fixed();
84 cfg.use_program(&pio.load_program(&prg.program), &[]);
85 sm.set_config(&cfg);
86
87 sm.set_enable(true);
88 Self { sm }
89 }
90
91 pub async fn read(&mut self) -> u32 {
92 self.sm.get_rxf_entry(0)
93 }
94}
95
96pub enum Direction {
97 Clockwise,
98 CounterClockwise,
99}
100
101#[embassy_executor::main]
102async fn main(_spawner: Spawner) {
103 let p = embassy_rp::init(Default::default());
104 let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
105
106 let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5);
107
108 loop {
109 info!("Count: {}", encoder.read().await);
110 Timer::after_millis(1000).await;
111 }
112}