Skip to content

Commit 9625716

Browse files
pferreirDirbaio
authored andcommitted
RP235x: support new FIFO options, set IE, OD on PIO pins.
1 parent 028de6d commit 9625716

File tree

7 files changed

+169
-10
lines changed

7 files changed

+169
-10
lines changed

cyw43-pio/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ documentation = "https://docs.embassy.dev/cyw43-pio"
1212
[dependencies]
1313
cyw43 = { version = "0.3.0", path = "../cyw43" }
1414
embassy-rp = { version = "0.3.0", path = "../embassy-rp" }
15-
pio-proc = "0.2"
16-
pio = "0.2.1"
15+
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
16+
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
1717
fixed = "1.23.1"
1818
defmt = { version = "0.3", optional = true }
1919

embassy-rp/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
139139
embedded-hal-async = { version = "1.0" }
140140
embedded-hal-nb = { version = "1.0" }
141141

142-
pio-proc = { version= "0.2" }
143-
pio = { version= "0.2.1" }
142+
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
143+
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
144144
rp2040-boot2 = "0.3"
145145
document-features = "0.2.10"
146146
sha2-const-stable = "0.1"

embassy-rp/src/pio/mod.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ pub enum FifoJoin {
5050
RxOnly,
5151
/// Tx fifo twice as deep. RX fifo disabled
5252
TxOnly,
53+
/// Enable random writes (`FJOIN_RX_PUT`) from the state machine (through ISR),
54+
/// and random reads from the system (using [`StateMachine::get_rxf_entry`]).
55+
#[cfg(feature = "_rp235x")]
56+
RxAsStatus,
57+
/// Enable random reads (`FJOIN_RX_GET`) from the state machine (through OSR),
58+
/// and random writes from the system (using [`StateMachine::set_rxf_entry`]).
59+
#[cfg(feature = "_rp235x")]
60+
RxAsControl,
61+
/// FJOIN_RX_PUT | FJOIN_RX_GET: RX can be used as a scratch register,
62+
/// not accesible from the CPU
63+
#[cfg(feature = "_rp235x")]
64+
PioScratch,
5365
}
5466

5567
/// Shift direction.
@@ -730,6 +742,17 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
730742
w.set_in_shiftdir(config.shift_in.direction == ShiftDirection::Right);
731743
w.set_autopull(config.shift_out.auto_fill);
732744
w.set_autopush(config.shift_in.auto_fill);
745+
746+
#[cfg(feature = "_rp235x")]
747+
{
748+
w.set_fjoin_rx_get(
749+
config.fifo_join == FifoJoin::RxAsControl || config.fifo_join == FifoJoin::PioScratch,
750+
);
751+
w.set_fjoin_rx_put(
752+
config.fifo_join == FifoJoin::RxAsStatus || config.fifo_join == FifoJoin::PioScratch,
753+
);
754+
w.set_in_count(config.in_count);
755+
}
733756
});
734757

735758
#[cfg(feature = "rp2040")]
@@ -907,6 +930,20 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
907930
pub fn rx_tx(&mut self) -> (&mut StateMachineRx<'d, PIO, SM>, &mut StateMachineTx<'d, PIO, SM>) {
908931
(&mut self.rx, &mut self.tx)
909932
}
933+
934+
/// Return the contents of the nth entry of the RX FIFO
935+
/// (should be used only when the FIFO config is set to [`FifoJoin::RxAsStatus`])
936+
#[cfg(feature = "_rp235x")]
937+
pub fn get_rxf_entry(&self, n: usize) -> u32 {
938+
PIO::PIO.rxf_putget(SM).putget(n).read()
939+
}
940+
941+
/// Set the contents of the nth entry of the RX FIFO
942+
/// (should be used only when the FIFO config is set to [`FifoJoin::RxAsControl`])
943+
#[cfg(feature = "_rp235x")]
944+
pub fn set_rxf_entry(&self, n: usize, val: u32) {
945+
PIO::PIO.rxf_putget(SM).putget(n).write_value(val)
946+
}
910947
}
911948

912949
/// PIO handle.
@@ -1053,6 +1090,12 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
10531090
/// of [`Pio`] do not keep pin registrations alive.**
10541091
pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> {
10551092
into_ref!(pin);
1093+
1094+
// enable the outputs
1095+
pin.pad_ctrl().write(|w| w.set_od(false));
1096+
// especially important on the 235x, where IE defaults to 0
1097+
pin.pad_ctrl().write(|w| w.set_ie(true));
1098+
10561099
pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _));
10571100
pin.pad_ctrl().write(|w| {
10581101
#[cfg(feature = "_rp235x")]

examples/rp/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" }
5555
static_cell = "2.1"
5656
portable-atomic = { version = "1.5", features = ["critical-section"] }
5757
log = "0.4"
58-
pio-proc = "0.2"
59-
pio = "0.2.1"
58+
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
59+
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
6060
rand = { version = "0.8.5", default-features = false }
6161
embedded-sdmmc = "0.7.0"
6262

examples/rp23/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" }
5555
static_cell = "2.1"
5656
portable-atomic = { version = "1.5", features = ["critical-section"] }
5757
log = "0.4"
58-
pio-proc = "0.2"
59-
pio = "0.2.1"
58+
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4", feature = ["rp2350"] }
59+
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4", feature = ["rp2350"] }
6060
rand = { version = "0.8.5", default-features = false }
6161
embedded-sdmmc = "0.7.0"
6262

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
7+
use defmt::info;
8+
use embassy_executor::Spawner;
9+
use embassy_rp::block::ImageDef;
10+
use embassy_rp::gpio::Pull;
11+
use embassy_rp::peripherals::PIO0;
12+
use embassy_rp::{bind_interrupts, pio};
13+
use embassy_time::Timer;
14+
use fixed::traits::ToFixed;
15+
use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
16+
use {defmt_rtt as _, panic_probe as _};
17+
18+
#[link_section = ".start_block"]
19+
#[used]
20+
pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe();
21+
22+
// Program metadata for `picotool info`
23+
#[link_section = ".bi_entries"]
24+
#[used]
25+
pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [
26+
embassy_rp::binary_info::rp_program_name!(c"example_pio_rotary_encoder_rxf"),
27+
embassy_rp::binary_info::rp_cargo_version!(),
28+
embassy_rp::binary_info::rp_program_description!(c"Rotary encoder (RXF)"),
29+
embassy_rp::binary_info::rp_program_build_attribute!(),
30+
];
31+
32+
bind_interrupts!(struct Irqs {
33+
PIO0_IRQ_0 => InterruptHandler<PIO0>;
34+
});
35+
36+
pub struct PioEncoder<'d, T: Instance, const SM: usize> {
37+
sm: StateMachine<'d, T, SM>,
38+
}
39+
40+
impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
41+
pub fn new(
42+
pio: &mut Common<'d, T>,
43+
mut sm: StateMachine<'d, T, SM>,
44+
pin_a: impl PioPin,
45+
pin_b: impl PioPin,
46+
) -> Self {
47+
let mut pin_a = pio.make_pio_pin(pin_a);
48+
let mut pin_b = pio.make_pio_pin(pin_b);
49+
pin_a.set_pull(Pull::Up);
50+
pin_b.set_pull(Pull::Up);
51+
52+
sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]);
53+
54+
let prg = pio_proc::pio_asm!(
55+
"start:"
56+
// encoder count is stored in X
57+
"mov isr, x"
58+
// and then moved to the RX FIFO register
59+
"mov rxfifo[0], isr"
60+
61+
// wait for encoder transition
62+
"wait 1 pin 1"
63+
"wait 0 pin 1"
64+
65+
"set y, 0"
66+
"mov y, pins[1]"
67+
68+
// update X depending on pin 1
69+
"jmp !y decr"
70+
71+
// this is just a clever way of doing x++
72+
"mov x, ~x"
73+
"jmp x--, incr"
74+
"incr:"
75+
"mov x, ~x"
76+
"jmp start"
77+
78+
// and this is x--
79+
"decr:"
80+
"jmp x--, start"
81+
);
82+
83+
let mut cfg = Config::default();
84+
cfg.set_in_pins(&[&pin_a, &pin_b]);
85+
cfg.fifo_join = FifoJoin::RxAsStatus;
86+
cfg.shift_in.direction = ShiftDirection::Left;
87+
cfg.clock_divider = 10_000.to_fixed();
88+
cfg.use_program(&pio.load_program(&prg.program), &[]);
89+
sm.set_config(&cfg);
90+
91+
sm.set_enable(true);
92+
Self { sm }
93+
}
94+
95+
pub async fn read(&mut self) -> u32 {
96+
self.sm.get_rxf_entry(0)
97+
}
98+
}
99+
100+
pub enum Direction {
101+
Clockwise,
102+
CounterClockwise,
103+
}
104+
105+
#[embassy_executor::main]
106+
async fn main(_spawner: Spawner) {
107+
let p = embassy_rp::init(Default::default());
108+
let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
109+
110+
let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5);
111+
112+
loop {
113+
info!("Count: {}", encoder.read().await);
114+
Timer::after_millis(1000).await;
115+
}
116+
}

tests/rp/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ embedded-io-async = { version = "0.6.1" }
3333
embedded-storage = { version = "0.3" }
3434
static_cell = "2"
3535
portable-atomic = { version = "1.5", features = ["critical-section"] }
36-
pio = "0.2"
37-
pio-proc = "0.2"
36+
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
37+
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
3838
rand = { version = "0.8.5", default-features = false }
3939

4040
[profile.dev]

0 commit comments

Comments
 (0)