diff options
| -rw-r--r-- | cyw43-pio/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-rp/Cargo.toml | 4 | ||||
| -rw-r--r-- | embassy-rp/src/pio/mod.rs | 46 | ||||
| -rw-r--r-- | examples/rp/Cargo.toml | 4 | ||||
| -rw-r--r-- | examples/rp23/Cargo.toml | 4 | ||||
| -rw-r--r-- | examples/rp23/src/bin/pio_rotary_encoder_rxf.rs | 116 | ||||
| -rw-r--r-- | tests/rp/Cargo.toml | 4 |
7 files changed, 172 insertions, 10 deletions
diff --git a/cyw43-pio/Cargo.toml b/cyw43-pio/Cargo.toml index 292cccf66..f52788ba3 100644 --- a/cyw43-pio/Cargo.toml +++ b/cyw43-pio/Cargo.toml | |||
| @@ -12,8 +12,8 @@ documentation = "https://docs.embassy.dev/cyw43-pio" | |||
| 12 | [dependencies] | 12 | [dependencies] |
| 13 | cyw43 = { version = "0.3.0", path = "../cyw43" } | 13 | cyw43 = { version = "0.3.0", path = "../cyw43" } |
| 14 | embassy-rp = { version = "0.3.0", path = "../embassy-rp" } | 14 | embassy-rp = { version = "0.3.0", path = "../embassy-rp" } |
| 15 | pio-proc = "0.2" | 15 | pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 16 | pio = "0.2.1" | 16 | pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 17 | fixed = "1.23.1" | 17 | fixed = "1.23.1" |
| 18 | defmt = { version = "0.3", optional = true } | 18 | defmt = { version = "0.3", optional = true } |
| 19 | 19 | ||
diff --git a/embassy-rp/Cargo.toml b/embassy-rp/Cargo.toml index 56cc39bbf..120e058ed 100644 --- a/embassy-rp/Cargo.toml +++ b/embassy-rp/Cargo.toml | |||
| @@ -139,8 +139,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" } | |||
| 139 | embedded-hal-async = { version = "1.0" } | 139 | embedded-hal-async = { version = "1.0" } |
| 140 | embedded-hal-nb = { version = "1.0" } | 140 | embedded-hal-nb = { version = "1.0" } |
| 141 | 141 | ||
| 142 | pio-proc = { version= "0.2" } | 142 | pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 143 | pio = { version= "0.2.1" } | 143 | pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 144 | rp2040-boot2 = "0.3" | 144 | rp2040-boot2 = "0.3" |
| 145 | document-features = "0.2.10" | 145 | document-features = "0.2.10" |
| 146 | sha2-const-stable = "0.1" | 146 | sha2-const-stable = "0.1" |
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs index 8916cbef0..7632d3168 100644 --- a/embassy-rp/src/pio/mod.rs +++ b/embassy-rp/src/pio/mod.rs | |||
| @@ -50,6 +50,18 @@ pub enum FifoJoin { | |||
| 50 | RxOnly, | 50 | RxOnly, |
| 51 | /// Tx fifo twice as deep. RX fifo disabled | 51 | /// Tx fifo twice as deep. RX fifo disabled |
| 52 | TxOnly, | 52 | 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, | ||
| 53 | } | 65 | } |
| 54 | 66 | ||
| 55 | /// Shift direction. | 67 | /// Shift direction. |
| @@ -730,6 +742,17 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 730 | w.set_in_shiftdir(config.shift_in.direction == ShiftDirection::Right); | 742 | w.set_in_shiftdir(config.shift_in.direction == ShiftDirection::Right); |
| 731 | w.set_autopull(config.shift_out.auto_fill); | 743 | w.set_autopull(config.shift_out.auto_fill); |
| 732 | w.set_autopush(config.shift_in.auto_fill); | 744 | 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 | } | ||
| 733 | }); | 756 | }); |
| 734 | 757 | ||
| 735 | #[cfg(feature = "rp2040")] | 758 | #[cfg(feature = "rp2040")] |
| @@ -907,6 +930,20 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 907 | pub fn rx_tx(&mut self) -> (&mut StateMachineRx<'d, PIO, SM>, &mut StateMachineTx<'d, PIO, SM>) { | 930 | pub fn rx_tx(&mut self) -> (&mut StateMachineRx<'d, PIO, SM>, &mut StateMachineTx<'d, PIO, SM>) { |
| 908 | (&mut self.rx, &mut self.tx) | 931 | (&mut self.rx, &mut self.tx) |
| 909 | } | 932 | } |
| 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 | } | ||
| 910 | } | 947 | } |
| 911 | 948 | ||
| 912 | /// PIO handle. | 949 | /// PIO handle. |
| @@ -993,6 +1030,9 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 993 | prog: &Program<SIZE>, | 1030 | prog: &Program<SIZE>, |
| 994 | origin: u8, | 1031 | origin: u8, |
| 995 | ) -> Result<LoadedProgram<'d, PIO>, usize> { | 1032 | ) -> Result<LoadedProgram<'d, PIO>, usize> { |
| 1033 | #[cfg(not(feature = "_rp235x"))] | ||
| 1034 | assert!(prog.version == pio::PioVersion::V0); | ||
| 1035 | |||
| 996 | let prog = RelocatedProgram::new_with_origin(prog, origin); | 1036 | let prog = RelocatedProgram::new_with_origin(prog, origin); |
| 997 | let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?; | 1037 | let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?; |
| 998 | Ok(LoadedProgram { | 1038 | Ok(LoadedProgram { |
| @@ -1053,6 +1093,12 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 1053 | /// of [`Pio`] do not keep pin registrations alive.** | 1093 | /// of [`Pio`] do not keep pin registrations alive.** |
| 1054 | pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { | 1094 | pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { |
| 1055 | into_ref!(pin); | 1095 | into_ref!(pin); |
| 1096 | |||
| 1097 | // enable the outputs | ||
| 1098 | pin.pad_ctrl().write(|w| w.set_od(false)); | ||
| 1099 | // especially important on the 235x, where IE defaults to 0 | ||
| 1100 | pin.pad_ctrl().write(|w| w.set_ie(true)); | ||
| 1101 | |||
| 1056 | pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _)); | 1102 | pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _)); |
| 1057 | pin.pad_ctrl().write(|w| { | 1103 | pin.pad_ctrl().write(|w| { |
| 1058 | #[cfg(feature = "_rp235x")] | 1104 | #[cfg(feature = "_rp235x")] |
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index d9decc2b0..5294ec477 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" } | |||
| 55 | static_cell = "2.1" | 55 | static_cell = "2.1" |
| 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
| 57 | log = "0.4" | 57 | log = "0.4" |
| 58 | pio-proc = "0.2" | 58 | pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 59 | pio = "0.2.1" | 59 | pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 60 | rand = { version = "0.8.5", default-features = false } | 60 | rand = { version = "0.8.5", default-features = false } |
| 61 | embedded-sdmmc = "0.7.0" | 61 | embedded-sdmmc = "0.7.0" |
| 62 | 62 | ||
diff --git a/examples/rp23/Cargo.toml b/examples/rp23/Cargo.toml index 4d99ecc72..8f9c14c5c 100644 --- a/examples/rp23/Cargo.toml +++ b/examples/rp23/Cargo.toml | |||
| @@ -55,8 +55,8 @@ embedded-storage = { version = "0.3" } | |||
| 55 | static_cell = "2.1" | 55 | static_cell = "2.1" |
| 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 56 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
| 57 | log = "0.4" | 57 | log = "0.4" |
| 58 | pio-proc = "0.2" | 58 | pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 59 | pio = "0.2.1" | 59 | pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 60 | rand = { version = "0.8.5", default-features = false } | 60 | rand = { version = "0.8.5", default-features = false } |
| 61 | embedded-sdmmc = "0.7.0" | 61 | embedded-sdmmc = "0.7.0" |
| 62 | 62 | ||
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 000000000..7a1046610 --- /dev/null +++ b/examples/rp23/src/bin/pio_rotary_encoder_rxf.rs | |||
| @@ -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 | } | ||
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 4278f7b2c..26f3f21f6 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -33,8 +33,8 @@ embedded-io-async = { version = "0.6.1" } | |||
| 33 | embedded-storage = { version = "0.3" } | 33 | embedded-storage = { version = "0.3" } |
| 34 | static_cell = "2" | 34 | static_cell = "2" |
| 35 | portable-atomic = { version = "1.5", features = ["critical-section"] } | 35 | portable-atomic = { version = "1.5", features = ["critical-section"] } |
| 36 | pio = "0.2" | 36 | pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 37 | pio-proc = "0.2" | 37 | pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" } |
| 38 | rand = { version = "0.8.5", default-features = false } | 38 | rand = { version = "0.8.5", default-features = false } |
| 39 | 39 | ||
| 40 | [profile.dev] | 40 | [profile.dev] |
