Merge #1395
1395: rp/pio: bit of a rework r=Dirbaio a=pennae the pio module is currently in a Bit of a State. this is far from all that's needed to make it more useful, but it's a start. Co-authored-by: pennae <github@quasiparticle.net>
This commit is contained in:
commit
ac0ea406f9
5 changed files with 287 additions and 446 deletions
|
@ -156,6 +156,7 @@ pub fn init(_config: config::Config) -> Peripherals {
|
|||
#[cfg(feature = "time-driver")]
|
||||
timer::init();
|
||||
dma::init();
|
||||
pio::init();
|
||||
}
|
||||
|
||||
peripherals
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,13 +4,15 @@
|
|||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_rp::gpio::{AnyPin, Pin};
|
||||
use embassy_rp::pio::{Pio0, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2};
|
||||
use embassy_rp::pio::{
|
||||
Pio0, PioCommon, PioCommonInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0,
|
||||
Sm1, Sm2,
|
||||
};
|
||||
use embassy_rp::pio_instr_util;
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
|
||||
fn setup_pio_task_sm0(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
|
||||
// Setup sm0
|
||||
|
||||
// Send data serially to pin
|
||||
|
@ -23,11 +25,11 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
|
|||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
let out_pin = sm.make_pio_pin(pin);
|
||||
let out_pin = pio.make_pio_pin(pin);
|
||||
let pio_pins = [&out_pin];
|
||||
sm.set_out_pins(&pio_pins);
|
||||
sm.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
|
||||
pio.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(sm, relocated.origin());
|
||||
sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32);
|
||||
sm.set_set_range(0, 1);
|
||||
let pio::Wrap { source, target } = relocated.wrap();
|
||||
|
@ -35,7 +37,10 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
|
|||
|
||||
sm.set_autopull(true);
|
||||
sm.set_out_shift_dir(ShiftDirection::Left);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>) {
|
||||
sm.set_enable(true);
|
||||
|
||||
let mut v = 0x0f0caffa;
|
||||
|
@ -46,16 +51,15 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) {
|
|||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
|
||||
fn setup_pio_task_sm1(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm1>) {
|
||||
// Setupm sm1
|
||||
|
||||
// Read 0b10101 repeatedly until ISR is full
|
||||
let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
sm.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
|
||||
pio.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(sm, relocated.origin());
|
||||
sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
|
||||
sm.set_set_range(0, 0);
|
||||
let pio::Wrap { source, target } = relocated.wrap();
|
||||
|
@ -63,6 +67,10 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
|
|||
|
||||
sm.set_autopush(true);
|
||||
sm.set_in_shift_dir(ShiftDirection::Right);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
|
||||
sm.set_enable(true);
|
||||
loop {
|
||||
let rx = sm.wait_pull().await;
|
||||
|
@ -70,8 +78,7 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) {
|
|||
}
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
|
||||
fn setup_pio_task_sm2(pio: &mut PioCommonInstance<Pio0>, sm: &mut PioStateMachineInstance<Pio0, Sm2>) {
|
||||
// Setup sm2
|
||||
|
||||
// Repeatedly trigger IRQ 3
|
||||
|
@ -85,13 +92,17 @@ async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
|
|||
".wrap",
|
||||
);
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
sm.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio.write_instr(relocated.origin() as usize, relocated.code());
|
||||
|
||||
let pio::Wrap { source, target } = relocated.wrap();
|
||||
sm.set_wrap(source, target);
|
||||
|
||||
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
|
||||
pio_instr_util::exec_jmp(sm, relocated.origin());
|
||||
sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32);
|
||||
}
|
||||
|
||||
#[embassy_executor::task]
|
||||
async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) {
|
||||
sm.set_enable(true);
|
||||
loop {
|
||||
sm.wait_irq(3).await;
|
||||
|
@ -104,9 +115,12 @@ async fn main(spawner: Spawner) {
|
|||
let p = embassy_rp::init(Default::default());
|
||||
let pio = p.PIO0;
|
||||
|
||||
let (_, sm0, sm1, sm2, ..) = pio.split();
|
||||
let (mut pio0, mut sm0, mut sm1, mut sm2, ..) = pio.split();
|
||||
|
||||
spawner.spawn(pio_task_sm0(sm0, p.PIN_0.degrade())).unwrap();
|
||||
setup_pio_task_sm0(&mut pio0, &mut sm0, p.PIN_0.degrade());
|
||||
setup_pio_task_sm1(&mut pio0, &mut sm1);
|
||||
setup_pio_task_sm2(&mut pio0, &mut sm2);
|
||||
spawner.spawn(pio_task_sm0(sm0)).unwrap();
|
||||
spawner.spawn(pio_task_sm1(sm1)).unwrap();
|
||||
spawner.spawn(pio_task_sm2(sm2)).unwrap();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use defmt::info;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_futures::join::join;
|
||||
use embassy_rp::pio::{PioPeripheral, PioStateMachine, ShiftDirection};
|
||||
use embassy_rp::pio::{PioCommon, PioPeripheral, PioStateMachine, ShiftDirection};
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
use embassy_rp::{pio_instr_util, Peripheral};
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
@ -19,7 +19,7 @@ fn swap_nibbles(v: u32) -> u32 {
|
|||
async fn main(_spawner: Spawner) {
|
||||
let p = embassy_rp::init(Default::default());
|
||||
let pio = p.PIO0;
|
||||
let (_, mut sm, ..) = pio.split();
|
||||
let (mut pio0, mut sm, ..) = pio.split();
|
||||
|
||||
let prg = pio_proc::pio_asm!(
|
||||
".origin 0",
|
||||
|
@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) {
|
|||
);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg.program);
|
||||
sm.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio0.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
|
||||
sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32);
|
||||
let pio::Wrap { source, target } = relocated.wrap();
|
||||
|
|
|
@ -6,7 +6,8 @@ use defmt::*;
|
|||
use embassy_executor::Spawner;
|
||||
use embassy_rp::gpio::{self, Pin};
|
||||
use embassy_rp::pio::{
|
||||
FifoJoin, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance,
|
||||
FifoJoin, PioCommon, PioCommonInstance, PioInstance, PioPeripheral, PioStateMachine, PioStateMachineInstance,
|
||||
ShiftDirection, SmInstance,
|
||||
};
|
||||
use embassy_rp::pio_instr_util;
|
||||
use embassy_rp::relocate::RelocatedProgram;
|
||||
|
@ -18,7 +19,7 @@ pub struct Ws2812<P: PioInstance, S: SmInstance> {
|
|||
}
|
||||
|
||||
impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
|
||||
pub fn new(mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
|
||||
pub fn new(mut pio: PioCommonInstance<P>, mut sm: PioStateMachineInstance<P, S>, pin: gpio::AnyPin) -> Self {
|
||||
// Setup sm0
|
||||
|
||||
// prepare the PIO program
|
||||
|
@ -49,11 +50,11 @@ impl<P: PioInstance, S: SmInstance> Ws2812<P, S> {
|
|||
let prg = a.assemble_with_wrap(wrap_source, wrap_target);
|
||||
|
||||
let relocated = RelocatedProgram::new(&prg);
|
||||
sm.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio.write_instr(relocated.origin() as usize, relocated.code());
|
||||
pio_instr_util::exec_jmp(&mut sm, relocated.origin());
|
||||
|
||||
// Pin config
|
||||
let out_pin = sm.make_pio_pin(pin);
|
||||
let out_pin = pio.make_pio_pin(pin);
|
||||
sm.set_set_pins(&[&out_pin]);
|
||||
sm.set_sideset_base_pin(&out_pin);
|
||||
sm.set_sideset_count(1);
|
||||
|
@ -115,7 +116,7 @@ async fn main(_spawner: Spawner) {
|
|||
info!("Start");
|
||||
let p = embassy_rp::init(Default::default());
|
||||
|
||||
let (_pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split();
|
||||
let (pio0, sm0, _sm1, _sm2, _sm3) = p.PIO0.split();
|
||||
|
||||
// This is the number of leds in the string. Helpfully, the sparkfun thing plus and adafruit
|
||||
// feather boards for the 2040 both have one built in.
|
||||
|
@ -124,7 +125,7 @@ async fn main(_spawner: Spawner) {
|
|||
|
||||
// For the thing plus, use pin 8
|
||||
// For the feather, use pin 16
|
||||
let mut ws2812 = Ws2812::new(sm0, p.PIN_8.degrade());
|
||||
let mut ws2812 = Ws2812::new(pio0, sm0, p.PIN_8.degrade());
|
||||
|
||||
// Loop forever making RGB values and pushing them out to the WS2812.
|
||||
loop {
|
||||
|
|
Loading…
Reference in a new issue