diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 29a8a3c53a..c1fb533ead 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml @@ -139,7 +139,7 @@ embedded-hal-async = { version = "1.0" } embedded-hal-nb = { version = "1.0" } pio-proc = {version= "0.2" } -pio = {version= "0.2.1" } +pio = { version= "0.2.1" } rp2040-boot2 = "0.3" document-features = "0.2.7" sha2-const-stable = "0.1" @@ -148,3 +148,8 @@ rp-binary-info = { version = "0.1.0", optional = true } [dev-dependencies] embassy-executor = { version = "0.6.0", path = "../embassy-executor", features = ["arch-std", "executor-thread"] } static_cell = { version = "2" } + +[patch.crates-io] +pio = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" } +pio-parser = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" } +pio-proc = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" } \ No newline at end of file diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index 72aa8f1049..cdac87a215 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs @@ -50,6 +50,18 @@ pub enum FifoJoin { RxOnly, /// Tx fifo twice as deep. RX fifo disabled TxOnly, + /// Enable random writes (`FJOIN_RX_PUT`) from the state machine (through ISR), + /// and random reads from the system (using [`StateMachine::get_rxf_entry`]). + #[cfg(feature = "_rp235x")] + RxAsStatus, + /// Enable random reads (`FJOIN_RX_GET`) from the state machine (through OSR), + /// and random writes from the system (using [`StateMachine::set_rxf_entry`]). + #[cfg(feature = "_rp235x")] + RxAsControl, + /// FJOIN_RX_PUT | FJOIN_RX_GET: RX can be used as a scratch register, + /// not accesible from the CPU + #[cfg(feature = "_rp235x")] + PioScratch, } /// Shift direction. @@ -730,6 +742,17 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { w.set_in_shiftdir(config.shift_in.direction == ShiftDirection::Right); w.set_autopull(config.shift_out.auto_fill); w.set_autopush(config.shift_in.auto_fill); + + #[cfg(feature = "_rp235x")] + { + w.set_fjoin_rx_get( + config.fifo_join == FifoJoin::RxAsControl || config.fifo_join == FifoJoin::PioScratch, + ); + w.set_fjoin_rx_put( + config.fifo_join == FifoJoin::RxAsStatus || config.fifo_join == FifoJoin::PioScratch, + ); + w.set_in_count(config.in_count); + } }); #[cfg(feature = "rp2040")] @@ -907,6 +930,20 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { pub fn rx_tx(&mut self) -> (&mut StateMachineRx<'d, PIO, SM>, &mut StateMachineTx<'d, PIO, SM>) { (&mut self.rx, &mut self.tx) } + + /// Return the contents of the nth entry of the RX FIFO + /// (should be used only when the FIFO config is set to [`FifoJoin::RxAsStatus`]) + #[cfg(feature = "_rp235x")] + pub fn get_rxf_entry(&self, n: usize) -> u32 { + PIO::PIO.rxf_putget(SM).putget(n).read() + } + + /// Set the contents of the nth entry of the RX FIFO + /// (should be used only when the FIFO config is set to [`FifoJoin::RxAsControl`]) + #[cfg(feature = "_rp235x")] + pub fn set_rxf_entry(&self, n: usize, val: u32) { + PIO::PIO.rxf_putget(SM).putget(n).write_value(val) + } } /// PIO handle. @@ -1053,6 +1090,12 @@ impl<'d, PIO: Instance> Common<'d, PIO> { /// of [`Pio`] do not keep pin registrations alive.** pub fn make_pio_pin(&mut self, pin: impl Peripheral
+ 'd) -> Pin<'d, PIO> {
into_ref!(pin);
+
+ // enable the outputs
+ pin.pad_ctrl().write(|w| w.set_od(false));
+ // especially important on the 235x, where IE defaults to 0
+ pin.pad_ctrl().write(|w| w.set_ie(true));
+
pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _));
#[cfg(feature = "_rp235x")]
pin.pad_ctrl().modify(|w| {
diff --git a/examples/rp23/Cargo.toml b/examples/rp23/Cargo.toml
index 087f6fd698..0addc74374 100644
--- a/examples/rp23/Cargo.toml
+++ b/examples/rp23/Cargo.toml
@@ -54,8 +54,8 @@ embedded-storage = { version = "0.3" }
static_cell = "2.1"
portable-atomic = { version = "1.5", features = ["critical-section"] }
log = "0.4"
-pio-proc = "0.2"
-pio = "0.2.1"
+pio-proc = { version = "0.2", feature = ["rp2350"] }
+pio = { version = "0.2.1", feature = ["rp2350"] }
rand = { version = "0.8.5", default-features = false }
embedded-sdmmc = "0.7.0"
@@ -77,3 +77,7 @@ embassy-futures = { path = "../../embassy-futures" }
embassy-time = { path = "../../embassy-time" }
embassy-time-driver = { path = "../../embassy-time-driver" }
embassy-embedded-hal = { path = "../../embassy-embedded-hal" }
+
+pio = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" }
+pio-parser = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" }
+pio-proc = { git="https://github.com/CBJamo/pio-rs.git", rev="72a5a7daa859b9d8a416564a2fbf849f58e51639" }
\ No newline at end of file
diff --git a/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs b/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
new file mode 100644
index 0000000000..7a1046610a
--- /dev/null
+++ b/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
@@ -0,0 +1,116 @@
+//! This example shows how to use the PIO module in the RP235x to read a quadrature rotary encoder.
+//! It differs from the other example in that it uses the RX FIFO as a status register
+
+#![no_std]
+#![no_main]
+
+use defmt::info;
+use embassy_executor::Spawner;
+use embassy_rp::block::ImageDef;
+use embassy_rp::gpio::Pull;
+use embassy_rp::peripherals::PIO0;
+use embassy_rp::{bind_interrupts, pio};
+use embassy_time::Timer;
+use fixed::traits::ToFixed;
+use pio::{Common, Config, FifoJoin, Instance, InterruptHandler, Pio, PioPin, ShiftDirection, StateMachine};
+use {defmt_rtt as _, panic_probe as _};
+
+#[link_section = ".start_block"]
+#[used]
+pub static IMAGE_DEF: ImageDef = ImageDef::secure_exe();
+
+// Program metadata for `picotool info`
+#[link_section = ".bi_entries"]
+#[used]
+pub static PICOTOOL_ENTRIES: [embassy_rp::binary_info::EntryAddr; 4] = [
+ embassy_rp::binary_info::rp_program_name!(c"example_pio_rotary_encoder_rxf"),
+ embassy_rp::binary_info::rp_cargo_version!(),
+ embassy_rp::binary_info::rp_program_description!(c"Rotary encoder (RXF)"),
+ embassy_rp::binary_info::rp_program_build_attribute!(),
+];
+
+bind_interrupts!(struct Irqs {
+ PIO0_IRQ_0 => InterruptHandler