embassy/examples/rp/src/bin/pio_dma.rs

85 lines
2.3 KiB
Rust
Raw Permalink Normal View History

//! This example shows powerful PIO module in the RP2040 chip.
2022-07-27 22:45:46 +02:00
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
use defmt::info;
use embassy_executor::Spawner;
use embassy_futures::join::join;
use embassy_rp::peripherals::PIO0;
use embassy_rp::pio::{Config, InterruptHandler, Pio, ShiftConfig, ShiftDirection};
use embassy_rp::{bind_interrupts, Peripheral};
use fixed::traits::ToFixed;
use fixed_macro::types::U56F8;
2022-07-27 22:45:46 +02:00
use {defmt_rtt as _, panic_probe as _};
bind_interrupts!(struct Irqs {
PIO0_IRQ_0 => InterruptHandler<PIO0>;
});
2022-07-27 22:45:46 +02:00
fn swap_nibbles(v: u32) -> u32 {
let v = (v & 0x0f0f_0f0f) << 4 | (v & 0xf0f0_f0f0) >> 4;
let v = (v & 0x00ff_00ff) << 8 | (v & 0xff00_ff00) >> 8;
(v & 0x0000_ffff) << 16 | (v & 0xffff_0000) >> 16
}
#[embassy_executor::main]
async fn main(_spawner: Spawner) {
let p = embassy_rp::init(Default::default());
let pio = p.PIO0;
let Pio {
mut common,
sm0: mut sm,
..
} = Pio::new(pio, Irqs);
2022-07-27 22:45:46 +02:00
let prg = pio_proc::pio_asm!(
".origin 0",
"set pindirs,1",
".wrap_target",
"set y,7",
"loop:",
"out x,4",
"in x,4",
"jmp y--, loop",
".wrap",
);
let mut cfg = Config::default();
cfg.use_program(&common.load_program(&prg.program), &[]);
cfg.clock_divider = (U56F8!(125_000_000) / U56F8!(10_000)).to_fixed();
cfg.shift_in = ShiftConfig {
auto_fill: true,
threshold: 32,
direction: ShiftDirection::Left,
};
cfg.shift_out = ShiftConfig {
auto_fill: true,
threshold: 32,
direction: ShiftDirection::Right,
};
2022-07-27 22:45:46 +02:00
sm.set_config(&cfg);
2022-07-27 22:45:46 +02:00
sm.set_enable(true);
let mut dma_out_ref = p.DMA_CH0.into_ref();
let mut dma_in_ref = p.DMA_CH1.into_ref();
let mut dout = [0x12345678u32; 29];
for i in 1..dout.len() {
dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7;
}
let mut din = [0u32; 29];
loop {
let (rx, tx) = sm.rx_tx();
2022-07-27 22:45:46 +02:00
join(
tx.dma_push(dma_out_ref.reborrow(), &dout),
rx.dma_pull(dma_in_ref.reborrow(), &mut din),
2022-07-27 22:45:46 +02:00
)
.await;
for i in 0..din.len() {
assert_eq!(din[i], swap_nibbles(dout[i]));
}
info!("Swapped {} words", dout.len());
}
}