mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
RP235x: support new FIFO options, set IE, OD on PIO pins.
This commit is contained in:
parent
028de6d640
commit
933e888ed0
@ -12,8 +12,8 @@ documentation = "https://docs.embassy.dev/cyw43-pio"
|
||||
[dependencies]
|
||||
cyw43 = { version = "0.3.0", path = "../cyw43" }
|
||||
embassy-rp = { version = "0.3.0", path = "../embassy-rp" }
|
||||
pio-proc = "0.2"
|
||||
pio = "0.2.1"
|
||||
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
fixed = "1.23.1"
|
||||
defmt = { version = "0.3", optional = true }
|
||||
|
||||
|
@ -139,8 +139,8 @@ embedded-hal-1 = { package = "embedded-hal", version = "1.0" }
|
||||
embedded-hal-async = { version = "1.0" }
|
||||
embedded-hal-nb = { version = "1.0" }
|
||||
|
||||
pio-proc = { version= "0.2" }
|
||||
pio = { version= "0.2.1" }
|
||||
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
rp2040-boot2 = "0.3"
|
||||
document-features = "0.2.10"
|
||||
sha2-const-stable = "0.1"
|
||||
|
@ -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.
|
||||
@ -993,6 +1030,9 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
|
||||
prog: &Program<SIZE>,
|
||||
origin: u8,
|
||||
) -> Result<LoadedProgram<'d, PIO>, usize> {
|
||||
#[cfg(not(feature = "_rp235x"))]
|
||||
assert!(prog.version == pio::PioVersion::V0);
|
||||
|
||||
let prog = RelocatedProgram::new_with_origin(prog, origin);
|
||||
let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?;
|
||||
Ok(LoadedProgram {
|
||||
@ -1053,6 +1093,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<P = impl PioPin + 'd> + '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 _));
|
||||
pin.pad_ctrl().write(|w| {
|
||||
#[cfg(feature = "_rp235x")]
|
||||
|
@ -55,8 +55,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 = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
embedded-sdmmc = "0.7.0"
|
||||
|
||||
|
@ -55,8 +55,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 = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
embedded-sdmmc = "0.7.0"
|
||||
|
||||
|
116
examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
Normal file
116
examples/rp23/src/bin/pio_rotary_encoder_rxf.rs
Normal file
@ -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<PIO0>;
|
||||
});
|
||||
|
||||
pub struct PioEncoder<'d, T: Instance, const SM: usize> {
|
||||
sm: StateMachine<'d, T, SM>,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance, const SM: usize> PioEncoder<'d, T, SM> {
|
||||
pub fn new(
|
||||
pio: &mut Common<'d, T>,
|
||||
mut sm: StateMachine<'d, T, SM>,
|
||||
pin_a: impl PioPin,
|
||||
pin_b: impl PioPin,
|
||||
) -> Self {
|
||||
let mut pin_a = pio.make_pio_pin(pin_a);
|
||||
let mut pin_b = pio.make_pio_pin(pin_b);
|
||||
pin_a.set_pull(Pull::Up);
|
||||
pin_b.set_pull(Pull::Up);
|
||||
|
||||
sm.set_pin_dirs(pio::Direction::In, &[&pin_a, &pin_b]);
|
||||
|
||||
let prg = pio_proc::pio_asm!(
|
||||
"start:"
|
||||
// encoder count is stored in X
|
||||
"mov isr, x"
|
||||
// and then moved to the RX FIFO register
|
||||
"mov rxfifo[0], isr"
|
||||
|
||||
// wait for encoder transition
|
||||
"wait 1 pin 1"
|
||||
"wait 0 pin 1"
|
||||
|
||||
"set y, 0"
|
||||
"mov y, pins[1]"
|
||||
|
||||
// update X depending on pin 1
|
||||
"jmp !y decr"
|
||||
|
||||
// this is just a clever way of doing x++
|
||||
"mov x, ~x"
|
||||
"jmp x--, incr"
|
||||
"incr:"
|
||||
"mov x, ~x"
|
||||
"jmp start"
|
||||
|
||||
// and this is x--
|
||||
"decr:"
|
||||
"jmp x--, start"
|
||||
);
|
||||
|
||||
let mut cfg = Config::default();
|
||||
cfg.set_in_pins(&[&pin_a, &pin_b]);
|
||||
cfg.fifo_join = FifoJoin::RxAsStatus;
|
||||
cfg.shift_in.direction = ShiftDirection::Left;
|
||||
cfg.clock_divider = 10_000.to_fixed();
|
||||
cfg.use_program(&pio.load_program(&prg.program), &[]);
|
||||
sm.set_config(&cfg);
|
||||
|
||||
sm.set_enable(true);
|
||||
Self { sm }
|
||||
}
|
||||
|
||||
pub async fn read(&mut self) -> u32 {
|
||||
self.sm.get_rxf_entry(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Direction {
|
||||
Clockwise,
|
||||
CounterClockwise,
|
||||
}
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p = embassy_rp::init(Default::default());
|
||||
let Pio { mut common, sm0, .. } = Pio::new(p.PIO0, Irqs);
|
||||
|
||||
let mut encoder = PioEncoder::new(&mut common, sm0, p.PIN_4, p.PIN_5);
|
||||
|
||||
loop {
|
||||
info!("Count: {}", encoder.read().await);
|
||||
Timer::after_millis(1000).await;
|
||||
}
|
||||
}
|
@ -33,8 +33,8 @@ embedded-io-async = { version = "0.6.1" }
|
||||
embedded-storage = { version = "0.3" }
|
||||
static_cell = "2"
|
||||
portable-atomic = { version = "1.5", features = ["critical-section"] }
|
||||
pio = "0.2"
|
||||
pio-proc = "0.2"
|
||||
pio-proc = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
pio = { git = "https://github.com/rp-rs/pio-rs", rev = "fa586448b0b223217eec8c92c19fe6823dd04cc4" }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
|
||||
[profile.dev]
|
||||
|
Loading…
x
Reference in New Issue
Block a user